zea.simulatorΒΆ

Frequency domain ultrasound simulator.

The simulator works in the frequency domain (RFFT domain) and simulates RF data as a superposition of scatterer responses. Every scatterer has a location and a magnitude.

To use it in your code, simply call the simulate_rf() function with the desired transmit scheme parameters and scatterers. To simulate a sequence of multiple frames, you can call simulate_rf() repeatedly with different scatterer positions and magnitudes and then stack the results.

There is a time-domain variant of the simulator in zea.simulator_time_domain.

Example usageΒΆ

A simple example of simulating RF data with a single scatterer at the center of the probe. For a more in depth example see the notebook: Simulating ultrasound data with zea.

>>> from zea.simulator import simulate_rf
>>> import numpy as np

>>> raw_data = simulate_rf(
...     scatterer_positions=np.array([[0, 0, 20e-3]]),
...     scatterer_magnitudes=np.array([1.0]),
...     probe_geometry=np.stack(
...         [np.linspace(-20e-3, 20e-3, 64), np.zeros(64), np.zeros(64)], axis=-1
...     ),
...     apply_lens_correction=True,
...     lens_thickness=1e-3,
...     lens_sound_speed=1000,
...     sound_speed=1540,
...     n_ax=1024,
...     center_frequency=5e6,
...     sampling_frequency=20e6,
...     t0_delays=np.zeros((1, 64)),
...     initial_times=np.zeros(1),
...     element_width=0.2e-3,
...     attenuation_coef=0.5,
...     tx_apodizations=np.ones((1, 64)),
...     t_peak=np.full(1, 1 / 5e6),
... )

Functions

apply_receive_chain(rf_data[, ...])

Add electronic noise and time gain compensation to noiseless RF.

attenuate(f, attenuation_coef, dist)

Applies attenuation to the signal in the frequency domain.

delay2(f, tau, n_fft, sampling_frequency)

Applies a delay in the frequency domain without phase wrapping.

elevation_slab_bucket([scatterer_positions, ...])

Prune scatterers outside of the elevation slab.

elevation_slab_mask(scatterer_positions, ...)

Zero out the scatterers an elevation lens never insonifies.

get_pulse_spectrum_fn(center_frequency[, ...])

Computes the spectrum of a sine that is windowed with a Hann window.

get_transducer_bandwidth_fn(...)

Computes the spectrum of a probe with a center frequency and bandwidth.

hann_fd(f, width)

The fourier transform of a hann window in the time domain with given width.

hann_unnormalized(x, width)

Hann window function that is 1 at the peak.

select_elevation_slab(scatterer_positions, ...)

Drop the scatterers an elevation lens never insonifies.

simulate_rf(scatterer_positions, ...[, ...])

Simulates RF data for a given set of scatterers.

spread(dist[, exponent, mindist])

Geometric spreading of the wavefront.

zea.simulator.apply_receive_chain(rf_data, noise_level_db=None, tgc_max_db=0.0, noise_seed=0, noise_reference=None)[source]ΒΆ

Add electronic noise and time gain compensation to noiseless RF.

Parameters:
  • rf_data (array-like) – Noiseless RF of shape (n_tx, n_ax, n_el, 1), optionally with a leading batch axis.

  • noise_level_db (float) – Noise floor in dB below the peak of rf_data. None disables the noise. Must be static when using jit compilation.

  • tgc_max_db (float) – Gain in dB at the last axial sample. 0 disables it. Must be static when using jit compilation.

  • noise_seed (int | SeedGenerator | jax.random.key, optional) – Seed for the noise. An int is stateless, so the same value gives the same realisation; vary it across transmit batches. None draws from the global generator and cannot be traced under jit.

  • noise_reference (float) – Reference amplitude for the noise level. If None, defaults to the rf_data maximum. Pass a fixed reference to avoid the noise level changing per transmit batch.

Returns:

RF with same shape as rf_data.

Return type:

array-like

zea.simulator.attenuate(f, attenuation_coef, dist)[source]ΒΆ

Applies attenuation to the signal in the frequency domain.

Parameters:
  • f (array-like) – The input frequencies.

  • attenuation_coef (float) – The attenuation coefficient in dB/cm/MHz.

  • dist (float) – The distance the signal has traveled.

Returns:

The spectrum of the attenuation.

Return type:

array-like

zea.simulator.delay2(f, tau, n_fft, sampling_frequency)[source]ΒΆ

Applies a delay in the frequency domain without phase wrapping.

Parameters:
  • f (array-like) – The input frequencies.

  • tau (float) – The delay to apply.

  • n_fft (int) – The number of samples in the FFT.

  • sampling_frequency (float) – The sampling frequency.

Returns:

The spectrum of the delay.

Return type:

array-like

zea.simulator.elevation_slab_bucket(scatterer_positions=None, scatterer_magnitudes=None, probe_geometry=None, element_height=None, elevation_lens=False, bucket_growth=2.0, **kwargs)[source]ΒΆ

Prune scatterers outside of the elevation slab. Round up to a power of 2 so jit can cache the approximate shape.

Returns:

pruned scatterers, or {} if the input is traced or pruning is disabled.

Return type:

dict

zea.simulator.elevation_slab_mask(scatterer_positions, probe_geometry, element_height)[source]ΒΆ

Zero out the scatterers an elevation lens never insonifies.

Returns:

1 inside the slab and 0 outside, of shape (n_scat,).

Return type:

array-like

zea.simulator.get_pulse_spectrum_fn(center_frequency, n_period=3.0, sampling_frequency=None)[source]ΒΆ

Computes the spectrum of a sine that is windowed with a Hann window.

Parameters:
  • center_frequency (float) – The center frequency of the transmit pulse.

  • n_period (float) – The number of periods to include in the pulse.

  • sampling_frequency (float) – Frequency used for scaling the spectrum such that a waveform recovered with ops.irfft has a unit peak (as ops.irfft divides the waveform by the sampling frequency).

Returns:

A function that computes the spectrum of the pulse for the input frequencies in Hz.

Return type:

spectrum_fn (callable)

zea.simulator.get_transducer_bandwidth_fn(probe_center_frequency, bandwidth)[source]ΒΆ

Computes the spectrum of a probe with a center frequency and bandwidth.

Parameters:
  • probe_center_frequency (float) – The center frequency of the probe.

  • bandwidth (float) – The bandwidth of the probe.

Returns

spectrum_fn (callable): A function that computes the spectrum of the pulse for the input frequencies in Hz.

zea.simulator.hann_fd(f, width)[source]ΒΆ

The fourier transform of a hann window in the time domain with given width.

zea.simulator.hann_unnormalized(x, width)[source]ΒΆ

Hann window function that is 1 at the peak. This means that the integral of the window function is not necessarily 1.

Parameters:
  • x (array-like) – The input values.

  • width (float) – The width of the window. This is the total width from -x to x. The window will be nonzero in the range [-width/2, width/2].

Returns:

The values of the Hann window function.

Return type:

hann_vals (array-like)

zea.simulator.select_elevation_slab(scatterer_positions, scatterer_magnitudes, probe_geometry, element_height)[source]ΒΆ

Drop the scatterers an elevation lens never insonifies.

Not jittable: the output length is data dependent. Under jit use elevation_slab_mask(), which zeroes magnitudes instead and keeps a static shape.

Returns:

the (positions, magnitudes) inside the slab.

Return type:

tuple

zea.simulator.simulate_rf(scatterer_positions, scatterer_magnitudes, probe_geometry, apply_lens_correction, lens_thickness, lens_sound_speed, sound_speed, n_ax, center_frequency, sampling_frequency, t0_delays, initial_times, element_width, attenuation_coef, tx_apodizations, t_peak, elevation_lens=False, element_height=None, max_chunk_gb=10.0, noise_level_db=None, tgc_max_db=0.0, noise_seed=0, noise_reference=None, scatter_exponent=2.0)[source]ΒΆ

Simulates RF data for a given set of scatterers.

Parameters:
  • scatterer_positions (array-like) – The positions of the scatterers [m] of shape (n_scat, 3).

  • scatterer_magnitudes (array-like) – The magnitudes of the scatterers of shape (n_scat,).

  • probe_geometry (array-like) – The geometry of the probe [m] of shape (n_el, 3).

  • apply_lens_correction (bool) – Whether to apply lens correction.

  • lens_thickness (float) – The thickness of the lens [m].

  • lens_sound_speed (float) – The speed of sound in the lens [m/s].

  • sound_speed (float) – The speed of sound in the medium [m/s].

  • n_ax (int) – The number of samples in the RF data.

  • center_frequency (float) – The center frequency of the transmit pulse [Hz].

  • sampling_frequency (float) – The sampling frequency of the RF data [Hz].

  • t0_delays (array-like) – The transmit delays [s] of shape (n_tx, n_el).

  • initial_times (array-like) – The initial times [s] of shape (n_tx,).

  • element_width (float) – The width of the elements [m].

  • attenuation_coef (float) – The attenuation coefficient [dB/cm/MHz].

  • tx_apodizations (array-like) – The transmit apodizations of shape (n_tx, n_el).

  • t_peak (array-like) – The time of the peak of the transmit pulse [s] of shape (n_tx,).

  • elevation_lens (bool) – Whether the probe has an elevation lens: drop scatterers outside the elevation slab, and focus transmit energy directly downwards (i.e. cylindrical instead of spherical spread). For efficient pruning scatterers outside the slab, use zea.ops.Simulate rather than calling simulate_rf directly.

  • element_height (float) – The elevation height of the elements [m], used for the elevation directivity and the elevation slab. If None, defaults to element_width.

  • max_chunk_gb (float) – Unused here; accepted so simulate_rf() and zea.simulator_time_domain.simulate_rf_td() share a call signature.

  • noise_level_db (float) – Electronic noise level in dB relative to the noiseless RF maximum. None disables the noise. Must be static under jit.

  • tgc_max_db (float) – Time gain compensation in dB at the last axial sample, ramped linearly in dB from 0 at the first. 0 disables it. Must be static under jit.

  • noise_seed (int | SeedGenerator | jax.random.key, optional) – Seed for the noise. Vary it across transmit batches to keep the realisations independent.

  • noise_reference (float) – Reference amplitude for the noise level. If None, defaults to the noiseless RF maximum. Pass a fixed reference to avoid the noise level changing per transmit batch. See apply_receive_chain().

  • scatter_exponent (float) – Weigh the scattered field by (f / center_frequency)**scatter_exponent. 2 is Rayleigh scattering (e.g. blood), myocardium is approximately 1.5, soft tissue 0.6-0.8. Must be static under jit.

Returns:

The simulated RF data of shape (n_tx, n_ax, n_el, 1).

Return type:

rf_data (array-like)

zea.simulator.spread(dist, exponent=1.0, mindist=0.001)[source]ΒΆ

Geometric spreading of the wavefront.

Parameters:
  • dist (array-like) – The distance the wave has traveled.

  • exponent (float) – 1 for spherical, 0.5 for cylindrical. An elevation lens focuses the transmitted energy to a slab, resulting in a cylindrical transmit and a spherical receive path.

  • mindist (float) – Distance that corresponds with unit gain.

Returns:

An amplitude factor in the shape of dist.

Return type:

array-like