Main methods

Signal methods

ultraspy.down_mix(d_data, central_freq, sampling_freq, t0, axis=-1, inplace=True)

Down-mixing operation, performs a phase rotation on our data to move the spectrum around 0 Hz (involving the returned signal to be complex). The down-mixing is performed along the time axis (last one by default). All the operations are performed on GPU using a CUDA kernel.

Parameters:
  • d_data (cupy.array) – The GPUArray data on which to perform the down-mixing (along last dimension). It must be of a complex type as the down-mixing will return a complex array

  • central_freq (float) – The central frequency of the signal (in Hz)

  • sampling_freq (float) – The sampling frequency of the signal (in Hz)

  • t0 (float) – The t0 of the recorded samples (in s)

  • axis (int) – The axis of the data to filter

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept.

Returns:

The down-mixed data if inplace is False, else case return None and d_data is modified directly

Return type:

None, cupy.array

ultraspy.filtfilt(d_data, bound, sampling_freq, filter_type, order=5, axis=-1, inplace=True)

Butterworth filtfilt, greatly inspired by Matlab’s filtfilt version, zero-phase forward and reverse digital filtering using CUDA kernels, it filters data using coefficients A and B describing the following difference equation:

y(n) = b(1)*x(n) + b(2)*x(n-1) + … + b(nb+1)*x(n-nb)
- a(2)*y(n-1) - … - a(na+1)*y(n-na)

with b and a, the coefficients we computed from the butter function (scipy).

Parameters:
  • d_data (cupy.array) – The GPUArray data where to apply the filter (along the last axis)

  • bound (float) – The critical frequency for the filtering, in Hz

  • sampling_freq (float) – The sampling frequency of the signal, in Hz

  • filter_type (str) – The type of the filter (‘low’ or ‘high’)

  • order (int) – The order of the filter (default to 5)

  • axis (int) – The axis of the data to filter

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept

Returns:

The filtered data if inplace is False, else case return None and d_data is modified directly

Return type:

None, cupy.array

ultraspy.rf2iq(d_data, central_freq, sampling_freq, t0, order=5, bandwidth=100, axis=-1, implementation='all_in_one', inplace=True)

Converts raw RFs data signals into I/Qs (In-Phase Quadrature) using CUDA kernels on GPU. Consists in a down-mixing operation (centers the spectrum at 0Hz), followed by a low-pass filter to keep only the newly centered at 0 spectrum (remove the old negative component). Note that it assumes that the time samples (fast time) are in the last axis of d_data.

Parameters:
  • d_data (cupy.array) – The GPUArray data to convert (along the last axis)

  • central_freq (float) – The central frequency of the signal

  • sampling_freq (float) – The sampling frequency of the data

  • t0 (float) – The initial time of recording (in s)

  • order (int) – The order of the low-pass filter

  • axis (int) – The axis of the data to convert

  • bandwidth (float) – The bandwidth of the probes. Default is set to 100, which means that the whole information is supposed (1. x f0)-wide, centered at f0. Thus, the low-pass filter is set to half (bandwidth x f0)

  • implementation (str) – The implementation to use for filtfilt (can be ‘memory_handler’, ‘all_in_one’ or ‘unique_coefficients’)

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept

Returns:

The converted data (I/Qs) if inplace is False, else case return None and d_data is modified directly

Return type:

None, cupy.array

ultraspy.matched_filter(d_data, ref_signal, domain='time', inplace=True)

Applies a matched filter to our data along the last axis, given a reference signal which is supposed to match. Only the version on time domain currently works, which is basically a cross-correlation of our data with the reference signal, using a zero padding to keep it center all the time.

Parameters:
  • d_data (cupy.array) – The GPUArray data where to apply the filter (along the last axis)

  • ref_signal (numpy.ndarray) – The reference signal (1D)

  • domain (str) – The domain to use (‘time’ (default) or ‘spectral’)

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept

Returns:

The match filtered data if inplace is False, else case return None and d_data is modified directly

Return type:

None, cupy.array

ultraspy.normalize(d_data, ref_value=None, inplace=True)

Simply normalizes a signal to values between -1 and 1. Note that it only works on float signals (RFs).

Parameters:
  • d_data (cupy.array) – The GPUArray data to normalize

  • ref_value (float) – A reference value for normalization, if set, the normalization will be done using the reference value.

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept

Returns:

The match filtered data if inplace is False, else case return None and d_data is modified directly

Return type:

None, cupy.array

Doppler methods

ultraspy.apply_wall_filter(d_data, mode, degree=1, inplace=True)

Applies a clutter filter along slow time (last dimension of our data by default). Four modes are available:

  • none: when there are no wall filter to apply, doesn’t do anything

  • mean: applies a basic mean filter (subtract the mean of the data along slow time)

  • poly: applies a polynomial filter. The polynomial regression consists in using orthogonal Legendre polynomial coefficients to remove the fitting polynomials from the data, which ends up to remove the low frequencies components. The degree is the upper degree of the polynomials we want to remove

  • hp_filter: applies a high-pass butterworth filter. The critical frequency is assumed to be a tenth of degree (HP filter of everything above 10% of the spectrum if degree = 1)

Parameters:
  • d_data (cupy.array) – The GPUArray on which to perform the clutter filter

  • mode (str) – The name of the clutter filter to use, can be ‘none’, ‘mean’, ‘poly’ or ‘hp_filter’

  • degree (int) – The order of our filter (or 10 * w_n if we do hp_filter)

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept

Returns:

The filtered data along slow time if inplace is False, else case return None and d_data is modified directly

Return type:

cupy.array

ultraspy.spatial_smoothing(d_data, k_size, window_type='hamming', inplace=True)

Performs a spatial smoothing on data, using a given window function to compute the squared convolution kernel… Two methods are implemented:

  • hamming: Performs a convolution with a squared hamming window of size (k_size, k_size)

  • median: applies a median filter on a squared spatial matrix (of size (k_size, k_size)). If complex numbers, do the median of both real and imaginary parts separately

Note: Median smoother is very slow for big sizes (expected by cupyx, as

detailed in github.com/cupy/cupy/issues/6453)

Parameters:
  • d_data (cupy.array) – The 2D GPUArray data stored on GPU, of dtype complex64 or float32

  • k_size (int) – The kernel size. Works better if it is an odd number, as the kernel can be centered on each pixel.

  • window_type (str) – The name of the windowing function to use, only ‘hamming’ (default) and ‘median’ are supported for now.

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept

Returns:

The smoothed data if inplace is False, else case return None and d_data is modified directly

Return type:

cupy.array

ultraspy.get_color_doppler_map(d_data, nyquist_velocity, smoothing='hamming', kernel=1)

Computes the color doppler map, which is using the correlation of our data along slow time (last dimension of data), which are then converted to doppler velocity using the Doppler formula. It also can perform a spatial smoothing of a given number of pixels.

\[v_{D} = -v_{c} . \Im \left (\frac{\log(data)}{\pi} \right )\]
Parameters:
  • d_data (cupy.array) – The GPUArray data stored on GPU, of dtype complex64

  • nyquist_velocity (float) – The nyquist velocity, can be determined using c * prf / (4 * f_c)

  • smoothing (str) – The smoothing method to use (either hamming or median)

  • kernel (int) – The size of the squared kernel for smoothing

Returns:

The color map, which is of the shape of d_data (except the slow time dimension), and of type np.float32

Return type:

cupy.array

ultraspy.get_power_doppler_map(d_data, smoothing='hamming', kernel=1)

Computes the power doppler map, which is using the mean of squared values along slow time (defined as the last dimension of data). The result is then returned in dB. It can also perform a spatial smoothing of a given number of pixels.

\[ \begin{align}\begin{aligned}\text{MS} = \frac{\sum_{i=1}^{n}{|\text{data}_{\ i}|^2}}{n}\\P_{D} = 10 . \frac{\log_{10}(\text{MS})}{\max(\text{MS})}\end{aligned}\end{align} \]
Parameters:
  • d_data (cupy.array) – The GPUArray data stored on GPU, of dtype complex64

  • smoothing (str) – The smoothing method to use (either hamming or median)

  • kernel (int) – The size of the squared kernel for smoothing

Returns:

The power map, which is of the shape of d_data (except the slow time dimension), and of type np.float32

Return type:

cupy.array

ultraspy.gpu.doppler.dual_frequency_unalias(d_data, beamformed_fs, f01, p, band, sound_speed, prf, smoothing='hamming', kernel=1)

Computes two Doppler maps with different central frequencies, that can be mapped together to propose an alias-free Color map. This is based on works of Ecarlat et al., IUS 2022, “Alias-free color Doppler using chirps”

Parameters:
  • d_data (numpy.ndarray) – The GPUArray beamformed IQs data stored on GPU, of dtype complex64

  • beamformed_fs (float) – The sampling frequency along the beamformed signal, in Hz

  • f01 (float) – The first central frequency to use, in Hz

  • p (int) – The p relation between f01 and f02

  • band (float) – The band of the filter, in Hz

  • sound_speed (float) – The speed of sound of the medium

  • prf (float) – The PRF used during the acquisition

  • smoothing (str) – The smoothing method to use (either hamming or median)

  • kernel (int) – The size of the squared kernel for smoothing

Returns:

The unaliased color map

Return type:

numpy.ndarray

Display methods

ultraspy.to_b_mode(d_data, ref_value=None, inplace=True)

Computes the B-Mode of our beamformed data (should have extracted the envelope first). Simply returns 20 * log10(data).

Parameters:
  • d_data (cupy.array) – The GPUArray data stored on GPU, of dtype float32 (we’ve extracted the envelope)

  • ref_value (float) – A reference value for normalization, if set, the normalization will be done using the reference value

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept

Returns:

The B-Mode image if inplace is False, else case return None and d_data is modified directly

Return type:

cupy.array

ultraspy.get_spectrum(d_data, sampling_freq, padding=0)

Returns the spectrum of a data signal.

Parameters:
  • d_data (cupy.array) – The signal (must be 1D)

  • sampling_freq (float) – The sampling frequency of the signal (in Hz)

  • padding (int) – The number of 0 time samples to pad if the data is not long enough

Returns:

The frequencies and their respective distribution

Return type:

tuple

ultraspy.get_doppler_colormap(use='matplotlib')

Returns a color map proposition for Doppler, based on typical echographs, from blue (flow going away from the probe), to red (going toward to).

Parameters:

use (str) – The lib which will use the colormap, either ‘matplotlib’ or ‘pyqt’

Returns:

The matplotlib map with the RGB value of our color maps

Return type:

matplotlib.colors.ListedMaps

Post-processing methods

ultraspy.distort_dynamic(d_b_mode, method_type, params, dynamic, norm=False, inplace=True)

Post-processing method to distort the dynamic of a B-Mode image (already in dB). This is applying a mathematical function, either curved or sigmoid to distort the values of the image in order to distort the dynamic. Note that this will clip the data between dynamic and 0.

Parameters:
  • d_b_mode (cupy.array) – the original B-Mode image, on GPU

  • method_type (str) – the name of the function to apply, either ‘curve’ or ‘sigmoid’

  • params (dict) – the parameters of the function: - if ‘curved’, expects the ‘curve’ argument (]0, 1[) - if ‘sigmoid’, expects the ‘steep’ (]0, 2]) and the ‘offset’ ([0, 5])

  • dynamic (int) – the dynamic for display, negative integer

  • norm (bool) – if set to True, the function is normed

  • inplace (bool) – If set to True, d_data is directly modified. Else case, a new slot is allocated on GPU, and the result is returned while d_data is kept

Returns:

The distorted B-Mode image

Return type:

numpy.ndarray