devices.xylo.syns61201.AFESim

class devices.xylo.syns61201.AFESim(*args, **kwargs)[source]

Bases: Module

A Module that simulates analog hardware for preprocessing audio and converting into spike features.

This module simulates the Xylo audio front-end stage. This is a signal-to-event core that consists of a number of band-pass filters, followed by rectifying event production simulating a spiking LIF neuron. The event rate in each channel is roughly correlated to the energy in each filter band.

Warning

  • The AFE contains frequency tripling internally. For accurate simulation, the sampling frequency must be at least 6 times higher than the highest frequency component in the filtering chain. This would be the centre frequency of the highest filter, plus half the BW of that signal.

  • To prevent signal aliasing, you should apply a low-pass filter to restrict the bandwidth of the input, to ensure you don’t exceed this target highest frequency.

  • Input to the module is in Volts. Input amplitude should be scaled to a maximum of 112mV RMS.

Note

  • By default, the module simulates HW mismatch in the analog encoding block. This is controlled on instantiation with the add_noise, add_offset and add_mismatch arguments on initialisation and the corresponding simulation parameters.

  • Mismatch can be re-sampled by calling the generate_mismatch() method.

See also

For example usage of the AFESim Module, see Using the analog frontend model

Attributes overview

class_name

Class name of self

dt

Simulation time-step in seconds

full_name

The full name of this module (class plus module name)

name

The name of this module, or an empty string if None

shape

The shape of this module

size

(DEPRECATED) The output size of this module

size_in

The input size of this module

size_out

The output size of this module

spiking_input

If True, this module receives spiking input.

spiking_output

If True, this module sends spiking output.

INPUT_MIC_MAX_AMPLITUDE

Maximum amplitude of sound that can be produced with microphone without having sever THD (above 1%)

MAX_INPUT_OFFSET

Maxmimum input offset from microphone (Default 0.)

F_CORNER_HIGHPASS

High pass corner frequency due to AC Coupling from BPF to FWR in Hz.

INPUT_LNA_MAX_AMPLITUDE

LNA Distortion parameter when the amplitude goes beyond its linear regime.

lna_gain_db

Low-noise amplifer gain in dB (Default 0.)

MAX_LNA_OFFSET

Maxmimum low-noise amplifier offset in mV (Default 5mV)

Q

Quality parameter for band-pass filters

Qs

Q factors for each filter

Fs

Sample frequency of input data

design_fcs

Centre frequency of each band-pass filter in Hz

fcs

Actual centre frequencies of each band-pass filter in Hz

bws

Actual bandwidth for each filter

design_bws

Bandwidths of each filter in Hz

ORDER_BPF

Band-pass filter order (Default 2)

MAX_BPF_OFFSET

Maxmum band-pass filter offset in mV (Default 5mV)

BPF_FC_SHIFT

Centre frequency band-pass filter shift in % (Default -5%)

Q_MIS_MATCH

Mismatch in Q in % (Default 10%)

FC_MIS_MATCH

Mismatch in centre freq.

C_IAF

Integrator Capacitance for IAF (Default 5e-12)

LEAKAGE

1.0e-9 : 1.0 nA for a cpacitor at volatage 1.0V

DIGITAL_COUNTER

Digital counter factor to reduce output spikes by.

THR_UP

Threshold for delta modulation in V (0.1--0.9) (Default 0.5V)

add_noise

Flag indicating that noise should be simulated during operation.

add_offset

Flag indicating that offset should be simulated during operation.

add_mismatch

Flag indicating that mismatch in the parameters should be simulated during operation.

num_workers

number of independent CPU units used for simulating the filters in the filterbank.

input_offset

Mismatch offset in the signal comming from microphone -- typically 0 due to AC coupling

lna_offset

Mismatch offset in low-noise amplifier

bpf_offset

Mismatch offset in band-pass filters

Q_mismatch

Mismatch in Q over band-pass filters

fc_mismatch

Mismatch in centre frequency for band-pass filters

bpf_fc_shift

Common shift in center frequencies due to temperature, etc.

lif_state

(np.ndarray) Internal state of the LIF neurons used to generate events

Methods overview

__init__(fs[,Β raster_period,Β ...])

param fs:

The sampling frequency of the input, in Hz

as_graph()

Convert this module to a computational graph

attributes_named(name)

Search for attributes of this or submodules by time

evolve(input[,Β record])

Evolve AFESim and return the generated spikes

generate_mismatch()

This function generates mismatch for the parameters of AFESim, based on analog non-idealities. It may be called: (i) once for all inputs simulated if we are interested in a single chip for all simulations. (ii) once for each input if we would like some sort of augmentation w.r.t. chip non-idealities.

modules()

Return a dictionary of all sub-modules of this module

parameters([family])

Return a nested dictionary of module and submodule Parameters

raster(spikes)

Rasterise the produced spikes within the rastering period

reset_parameters()

Reset all parameters in this module

reset_state()

Reset the state of this module

set_attributes(new_attributes)

Set the attributes and sub-module attributes from a dictionary

simulation_parameters([family])

Return a nested dictionary of module and submodule SimulationParameters

state([family])

Return a nested dictionary of module and submodule States

timed([output_num,Β dt,Β add_events])

Convert this module to a TimedModule

BPF_FC_SHIFT: P_float

Centre frequency band-pass filter shift in % (Default -5%)

Type:

float

C_IAF: P_float

Integrator Capacitance for IAF (Default 5e-12)

Type:

float

DIGITAL_COUNTER: P_int

Digital counter factor to reduce output spikes by. Default 4 (by a factor 4)

Type:

int

FC_MIS_MATCH: P_float

Mismatch in centre freq. in % (Default 5%)

Type:

float

F_CORNER_HIGHPASS: P_float

High pass corner frequency due to AC Coupling from BPF to FWR in Hz. (Default 20 Hz)

Type:

float

Fs: P_float

Sample frequency of input data

Type:

float

INPUT_LNA_MAX_AMPLITUDE: P_float

LNA Distortion parameter when the amplitude goes beyond its linear regime. Default 0.01

Type:

float

INPUT_MIC_MAX_AMPLITUDE: P_float

Maximum amplitude of sound that can be produced with microphone without having sever THD (above 1%)

Type:

float

LEAKAGE: P_float

1.0e-9 : 1.0 nA for a cpacitor at volatage 1.0V

Type:

float

Type:

Leakage conductance for LIF neuron producing the spikes. Default

MAX_BPF_OFFSET: P_float

Maxmum band-pass filter offset in mV (Default 5mV)

Type:

float

MAX_INPUT_OFFSET: P_float

Maxmimum input offset from microphone (Default 0.)

Type:

float

MAX_LNA_OFFSET: P_float

Maxmimum low-noise amplifier offset in mV (Default 5mV)

Type:

float

ORDER_BPF: P_int

Band-pass filter order (Default 2)

Type:

int

Q: P_int

Quality parameter for band-pass filters

Type:

int

Q_MIS_MATCH: P_float

Mismatch in Q in % (Default 10%)

Type:

float

Q_mismatch: P_ndarray

Mismatch in Q over band-pass filters

Type:

float

Qs: np.ndarray

Q factors for each filter

Type:

np.ndarray

THR_UP: P_float

Threshold for delta modulation in V (0.1–0.9) (Default 0.5V)

Type:

float

_LNA_evolve(sig_in: ndarray, v_corner: float, lna_distortion_level: float, max_output: float)[source]

this function takes the nonlinearity due to LNA into account.

Parameters:
  • sig_in (np.ndarray) – input signal received from the microphone.

  • v_corner (float) – the maximum linear range of the LNA.

  • lna_distortion_level (float) – the nonlinear distortion level added by LNA.

  • max_output (float) – maximum signal amplitude in the whole chip.

_MIC_evolve(sig_in: ndarray, v_corner: float, THD_level, max_output: float)[source]

this function incorporates the effect of third-order distortion in the input audio signal.

Parameters:
  • sig_in (np.ndarray) – 1-dim input signal.

  • v_corner (float) – voltage level at which THD is equal to THD_level.

  • THD_level (float, optional) – level of third-order distortion.

  • max_output (float) – maximum signal amplitude in the whole chip.

__init__(fs: int, raster_period: float = 0.01, max_spike_per_raster_period: int = 15, add_noise: bool = True, add_offset: bool = True, add_mismatch: bool = True, seed: int = 3774040275, num_workers: int = 1, *args, **kwargs)[source]
Parameters:
  • fs (int) –

    The sampling frequency of the input, in Hz NOTE:

    1. AFE contains frequency tripling in LNA and also in microphone. So the maximum representable frequency is fs/6.

    2. If this frequency is different than the sampling frequency of the audio, the frequencies are proportionally shifted and extracted spikes features will be wrong.

  • (float) (raster_period) –

  • (int) (max_spike_per_raster_period) –

  • add_noise (bool) – Enables / disables the simulated noise generated by the AFE. Default: True, include noise

  • add_offset (bool) – If True (default), add mismatch offset to each filter

  • add_mismatch (bool) – If True (default), add simualted mismatch to each filter

  • seed (int) – The AFE is subject to mismatch, this can be seeded by providing an integer seed. Default: random seed. Provide None to prevent seeding.

  • num_workers (int) – Number of cpu units used to speed up filter computation. Default: 1.

_abc_impl = <_abc._abc_data object>
_auto_batch(data: ndarray, states: Tuple = (), target_shapes: Tuple | None = None) Tuple[ndarray, Tuple[ndarray]]

Automatically replicate states over batches and verify input dimensions

Examples

>>> data, (state0, state1, state2) = self._auto_batch(data, (self.state0, self.state1, self.state2))

This will verify that data has the correct final dimension (i.e. self.size_in).

If data has only two dimensions (T, Nin), then it will be augmented to (1, T, Nin). The individual states will be replicated out from shape (a, b, c, ...) to (n_batches, a, b, c, ...) and returned.

If data has only a single dimension (T,), it will be expanded to (1, T, self.size_in).

state0, state1, state2 will be replicated out along the batch dimension.

>>> data, (state0,) = self._auto_batch(data, (self.state0,), ((10, -1, self.size_in),))

Attempt to replicate state0 to a specified size (10, -1, self.size_in).

Parameters:
  • data (np.ndarray) – Input data tensor. Either (batches, T, Nin) or (T, Nin)

  • states (Tuple) – Tuple of state variables. Each will be replicated out over batches by prepending a batch dimension

  • target_shapes (Tuple) – A tuple of target size tuples, each corresponding to each state argument. The individual states will be replicated out to match the corresponding target sizes. If not provided (the default), then states will be only replicated along batches.

Returns:

(np.ndarray, Tuple[np.ndarray]) data, states

_butter_bandpass(lowcut: float, highcut: float, fs: float, order: int = 2) Tuple[float, float][source]

Build a Butterworth bandpass filter from specification

Parameters:
  • lowcut (float) – Low-cut frequency in Hz

  • highcut (float) – High-cut frequency in Hz

  • fs (float) – Sampling frequecy in Hz

  • order (int) – Order of the filter

Returns: (float, float): b, a

Parameters for the bandpass filter

_butter_bandpass_filter(data: ndarray, lowcut: float, highcut: float, fs: float, order: int = 2) ndarray[source]

Filter data with a bandpass Butterworth filter, according to specifications

Parameters:
  • data (np.ndarray) – Input data with shape (T, N)

  • lowcut (float) – Low-cut frequency in Hz

  • highcut (float) – High-cut frequency in Hz

  • fs (float) – Sampling frequency in Hz

  • order (int) – Order of the filter

Returns: np.ndarray: Filtered data with shape (T, N)

_butter_highpass(cutoff: float, fs: float, order: int = 1) Tuple[float, float][source]

Build a Butterworth high-pass filter from specifications

Parameters:
  • cutoff (float) – High-pass cutoff frequency in Hz

  • fs (float) – Sampling rate in Hz

  • order (int) – Order of the filter

Returns: (float, float): b, a

Parameters for the high-pass filter

_butter_highpass_filter(data: ndarray, cutoff: float, fs: float, order: int = 1) ndarray[source]

Filter some data with a Butterworth high-pass filter from specifications

Parameters:
  • data (np.ndarray) – Array of input data to filter, with shape (T, N)

  • cutoff (float) – Cutoff frequency of the high-pass filter, in Hz

  • fs (float) – Sampling frequency of data, in Hz

  • order (int) – Order of the Butterwoth filter

Returns: np.ndarray: Filtered output data with shape (T, N)

_force_set_attributes

(bool) If True, do not sanity-check attributes when setting.

_generateNoise(T, Fs: float = 16000.0, VRMS_SQHZ: float = 1e-06, F_KNEE: float = 1000.0, F_ALPHA: float = 1.4) ndarray[source]

Generate band-limited noise, for use in simulating the AFE architecture

Parameters:
  • x (np.ndarray) – Input signal defining desired shape of noise (T,)

  • Fs (float) – Sampling frequency in Hz

  • VRMS_SQHZ (float) –

  • F_KNEE (float) –

  • F_ALPHA (float) –

Returns: np.ndarray: Generated noise with shape (T,)

_get_attribute_family(type_name: str, family: Tuple | List | str | None = None) dict

Search for attributes of this module and submodules that match a given family

This method can be used to conveniently get all weights for a network; or all time constants; or any other family of parameters. Parameter families are defined simply by a string: "weights" for weights; "taus" for time constants, etc. These strings are arbitrary, but if you follow the conventions then future developers will thank you (that includes you in six month’s time).

Parameters:
  • type_name (str) – The class of parameters to search for. Must be one of ["Parameter", "SimulationParameter", "State"] or another future subclass of ParameterBase

  • family (Union[str, Tuple[str]]) – A string or list or tuple of strings, that define one or more attribute families to search for

Returns:

A nested dictionary of attributes that match the provided type_name and family

Return type:

dict

_get_attribute_registry() Tuple[Dict, Dict]

Return or initialise the attribute registry for this module

Returns:

registered_attributes, registered_modules

Return type:

(tuple)

_has_registered_attribute(name: str) bool

Check if the module has a registered attribute

Parameters:

name (str) – The name of the attribute to check

Returns:

True if the attribute name is in the attribute registry, False otherwise.

Return type:

bool

_in_Module_init

(bool) If exists and True, indicates that the module is in the __init__ chain.

_name: str | None

Name of this module, if assigned

_register_attribute(name: str, val: ParameterBase)

Record an attribute in the attribute registry

Parameters:
  • name (str) – The name of the attribute to register

  • val (ParameterBase) – The ParameterBase subclass object to register. e.g. Parameter, SimulationParameter or State.

_register_module(name: str, mod: ModuleBase)

Register a sub-module in the module registry

Parameters:
  • name (str) – The name of the module to register

  • mod (ModuleBase) – The ModuleBase object to register

_reset_attribute(name: str) ModuleBase

Reset an attribute to its initialisation value

Parameters:

name (str) – The name of the attribute to reset

Returns:

For compatibility with the functional API

Return type:

self (Module)

_sampling_spikes(spikes: ndarray, count: int) ndarray[source]

Down-sample events in a signal, by passing one in every N events

Parameters:
  • spikes (np.ndarray) – Raster (T, N) of events

  • count (int) – Number of events to ignore before passing one event

Returns: np.ndarray: Raster (T, N) of down-sampled events

_shape

The shape of this module

_spiking_input: bool

Whether this module receives spiking input

_spiking_output: bool

Whether this module produces spiking output

_submodulenames: List[str]

Registry of sub-module names

_wrap_recorded_state(state_dict: dict, t_start: float = 0.0) dict[source]

Convert a recorded dictionary to a TimeSeries representation

This method is optional, and is provided to make the timed() conversion to a TimedModule work better. You should override this method in your custom Module, to wrap each element of your recorded state dictionary as a TimeSeries

Parameters:
  • state_dict (dict) – A recorded state dictionary as returned by evolve()

  • t_start (float) – The initial time of the recorded state, to use as the starting point of the time series

Returns:

The mapped recorded state dictionary, wrapped as TimeSeries objects

Return type:

Dict[str, TimeSeries]

add_mismatch: P_bool

Flag indicating that mismatch in the parameters should be simulated during operation. Default True

Type:

bool

add_noise: P_bool

Flag indicating that noise should be simulated during operation. Default True

Type:

bool

add_offset: P_bool

Flag indicating that offset should be simulated during operation. Default True

Type:

bool

as_graph() GraphModuleBase

Convert this module to a computational graph

Returns:

The computational graph corresponding to this module

Return type:

GraphModuleBase

Raises:

NotImplementedError – If as_graph() is not implemented for this subclass

attributes_named(name: Tuple[str] | List[str] | str) dict

Search for attributes of this or submodules by time

Parameters:

name (Union[str, Tuple[str]) – The name of the attribute to search for

Returns:

A nested dictionary of attributes that match name

Return type:

dict

bpf_fc_shift: P_float

Common shift in center frequencies due to temperature, etc.

Type:

float

bpf_offset: P_ndarray

Mismatch offset in band-pass filters

Type:

float

bws: np.ndarray

Actual bandwidth for each filter

Type:

np.ndarray

property class_name: str

Class name of self

Type:

str

design_bws: P_ndarray

Bandwidths of each filter in Hz

Type:

np.ndarray

design_fcs: P_ndarray

Centre frequency of each band-pass filter in Hz

Type:

np.ndarray

property dt: float

Simulation time-step in seconds

Returns:

Simulation time-step

Return type:

float

evolve(input: ndarray, record: bool = False, *args, **kwargs) Tuple[ndarray, dict, dict][source]

Evolve AFESim and return the generated spikes

Parameters:
  • input (np.ndarray, optional) – input audio signal.

  • record (bool, optional) – Record the internal state of AFESim during evolution. Defaults to False.

Raises:

ValueError – If the input data is not 1D

Returns:

Output events (T, 16), where each bin contains the count of events in that bin. dict: Internal state of the module at the end of evolution dict: Recording dictionary if requested, otherwise an empty dictionary

Return type:

np.ndarray

fc_mismatch: P_ndarray

Mismatch in centre frequency for band-pass filters

Type:

float

fcs: np.ndarray

Actual centre frequencies of each band-pass filter in Hz

Type:

np.ndarray

property full_name: str

The full name of this module (class plus module name)

Type:

str

generate_mismatch()[source]

This function generates mismatch for the parameters of AFESim, based on analog non-idealities. It may be called:

  1. once for all inputs simulated if we are interested in a single chip for all simulations.

  2. once for each input if we would like some sort of augmentation w.r.t. chip non-idealities.

input_offset: P_float

Mismatch offset in the signal comming from microphone – typically 0 due to AC coupling

Type:

float

lif_state: P_ndarray

(np.ndarray) Internal state of the LIF neurons used to generate events

lna_gain_db: P_float

Low-noise amplifer gain in dB (Default 0.)

Type:

float

lna_offset: P_float

Mismatch offset in low-noise amplifier

Type:

float

modules() Dict

Return a dictionary of all sub-modules of this module

Returns:

A dictionary containing all sub-modules. Each item will be named with the sub-module name.

Return type:

dict

property name: str

The name of this module, or an empty string if None

Type:

str

num_workers: P_int

number of independent CPU units used for simulating the filters in the filterbank. Default 1

Type:

int

parameters(family: Tuple | List | str | None = None) Dict

Return a nested dictionary of module and submodule Parameters

Use this method to inspect the Parameters from this and all submodules. The optional argument family allows you to search for Parameters in a particular family β€” for example "weights" for all weights of this module and nested submodules.

Although the family argument is an arbitrary string, reasonable choises are "weights", "taus" for time constants, "biases" for biases…

Examples

Obtain a dictionary of all Parameters for this module (including submodules):

>>> mod.parameters()
dict{ ... }

Obtain a dictionary of Parameters from a particular family:

>>> mod.parameters("weights")
dict{ ... }
Parameters:

family (str) – The family of Parameters to search for. Default: None; return all parameters.

Returns:

A nested dictionary of Parameters of this module and all submodules

Return type:

dict

raster(spikes: ndarray)[source]

Rasterise the produced spikes within the rastering period

Parameters:

spikes (np.ndarray) – input spikes of dimension T x F where F: number of filters.

reset_parameters()

Reset all parameters in this module

Returns:

The updated module is returned for compatibility with the functional API

Return type:

Module

reset_state() ModuleBase

Reset the state of this module

Returns:

The updated module is returned for compatibility with the functional API

Return type:

Module

set_attributes(new_attributes: dict) ModuleBase

Set the attributes and sub-module attributes from a dictionary

This method can be used with the dictionary returned from module evolution to set the new state of the module. It can also be used to set multiple parameters of a module and submodules.

Examples

Use the functional API to evolve, obtain new states, and set those states:

>>> _, new_state, _ = mod(input)
>>> mod = mod.set_attributes(new_state)

Obtain a parameter dictionary, modify it, then set the parameters back:

>>> params = mod.parameters()
>>> params['w_input'] *= 0.
>>> mod.set_attributes(params)
Parameters:

new_attributes (dict) – A nested dictionary containing parameters of this module and sub-modules.

property shape: tuple

The shape of this module

Type:

tuple

simulation_parameters(family: Tuple | List | str | None = None) Dict

Return a nested dictionary of module and submodule SimulationParameters

Use this method to inspect the SimulationParameters from this and all submodules. The optional argument family allows you to search for SimulationParameters in a particular family.

Examples

Obtain a dictionary of all SimulationParameters for this module (including submodules):

>>> mod.simulation_parameters()
dict{ ... }
Parameters:

family (str) – The family of SimulationParameters to search for. Default: None; return all SimulationParameter attributes.

Returns:

A nested dictionary of SimulationParameters of this module and all submodules

Return type:

dict

property size: int

(DEPRECATED) The output size of this module

Type:

int

property size_in: int

The input size of this module

Type:

int

property size_out: int

The output size of this module

Type:

int

property spiking_input: bool

If True, this module receives spiking input. If False, this module expects continuous input.

Type:

bool

property spiking_output

If True, this module sends spiking output. If False, this module sends continuous output.

Type:

bool

state(family: Tuple | List | str | None = None) Dict

Return a nested dictionary of module and submodule States

Use this method to inspect the States from this and all submodules. The optional argument family allows you to search for States in a particular family.

Examples

Obtain a dictionary of all States for this module (including submodules):

>>> mod.state()
dict{ ... }
Parameters:

family (str) – The family of States to search for. Default: None; return all State attributes.

Returns:

A nested dictionary of States of this module and all submodules

Return type:

dict

timed(output_num: int = 0, dt: float | None = None, add_events: bool = False)

Convert this module to a TimedModule

Parameters:
  • output_num (int) – Specify which output of the module to take, if the module returns multiple output series. Default: 0, take the first (or only) output.

  • dt (float) – Used to provide a time-step for this module, if the module does not already have one. If self already defines a time-step, then self.dt will be used. Default: None

  • add_events (bool) – Iff True, the TimedModule will add events occurring on a single timestep on input and output. Default: False, don’t add time steps.

Returns: TimedModule: A timed module that wraps this module