zea.beamform.admire¶
Aperture Domain Model Image REconstruction (ADMIRE).
ADMIRE is a model-based beamformer that suppresses off-axis and multipath (reverberation) clutter. Time-delayed channel data is split into short axial windows, each window is taken to the frequency domain, and at every frequency the aperture-domain signal (one complex value per element) is fitted with a linear model of the wavefronts that point scatterers would produce across the aperture. Scatterers inside a small region of interest (ROI) around the window center are kept; everything explained by scatterers outside the ROI is clutter and is discarded. The model is fitted with elastic-net regularized least squares, solved with cyclic coordinate descent.
The implementation is split in two parts:
generate_admire_models()precomputes the models with NumPy. They depend only on the imaging geometry (axial sampling, sound speed, center frequency, element pitch and sub-aperture size), so they are computed once and reused.apply_admire()fits the models to channel data and reconstructs the decluttered channel data with Keras ops, so it runs (and JIT compiles) on every backend.
The beamformer is usually used through zea.ops.ADMIRE, which handles
the data layout of a zea pipeline.
Note
The reference code and its default settings target focused, walked-aperture
scans. Compounded plane-wave data works too, but may need retuned settings.
Part of ADMIRE’s contrast gain over DAS acts as a stretch of the dynamic range,
to which the gCNR (zea.metrics.gcnr()) is insensitive.
Important
This is a zea implementation of ADMIRE. For the original MATLAB, C and
CUDA code of the Vanderbilt BEAM Lab, see
VU-BEAM-Lab/ADMIRE.
Note
The model generation, its calibration constants and the model application
are ported from the reference code, Copyright 2020 Christopher Khan,
Kazuyuki Dei, Siegfried Schlunk and Brett Byram. The coordinate descent
solver is ported from ccd_double_precision.c, Copyright 2020 Christopher
Khan. Both are licensed under the
Apache License 2.0;
see the reference repository’s NOTICE file. The ICA is the FOBI code
(ica.m) from Shlens’ tutorial, which the reference includes.
Changes from the reference: the code is translated to NumPy (model generation) and Keras ops (model fitting); all lines, windows and frequencies are fitted in one batched solve; IQ data is supported in addition to RF data; the phase of the ICA eigenvectors is fixed so the models are reproducible across platforms; and the wavenumber calibration table is matched to the nearest listed center frequency instead of exactly.
References
B. Byram, K. Dei, J. Tierney, and D. Dumont, “A Model and Regularization Scheme for Ultrasonic Beamforming Clutter Reduction,” IEEE Transactions on Ultrasonics, Ferroelectrics, and Frequency Control, vol. 62, no. 11, pp. 1913–1927, 2015. doi.org/10.1109/TUFFC.2015.007004
K. Dei, S. Schlunk, and B. Byram, “Computationally Efficient Implementation of Aperture Domain Model Image Reconstruction,” IEEE Transactions on Ultrasonics, Ferroelectrics, and Frequency Control, vol. 66, no. 10, pp. 1546–1559, 2019. doi.org/10.1109/TUFFC.2019.2924824
C. Khan, K. Dei, S. Schlunk, K. Ozgun, and B. Byram, “A Real-Time, GPU-Based Implementation of Aperture Domain Model Image REconstruction,” IEEE Transactions on Ultrasonics, Ferroelectrics, and Frequency Control, vol. 68, no. 6, pp. 2101–2116, 2021. doi.org/10.1109/TUFFC.2021.3056334
C. Khan and B. Byram, “GENRE (GPU Elastic-Net REgression): A CUDA-Accelerated Package for Massively Parallel Linear Regression with Elastic-Net Regularization,” Journal of Open Source Software, vol. 5, no. 54, p. 2644, 2020. doi.org/10.21105/joss.02644
B. Byram and M. Jakovljevic, “Ultrasonic Multipath and Beamforming Clutter Reduction: A Chirp Model Approach,” IEEE Transactions on Ultrasonics, Ferroelectrics, and Frequency Control, vol. 61, no. 3, pp. 428–440, 2014. doi.org/10.1109/TUFFC.2014.2928
J. Shlens, “A Tutorial on Independent Component Analysis,” arXiv preprint, 2014. arXiv:1404.2986
J.-F. Cardoso, “Source Separation Using Higher Order Moments,” in International Conference on Acoustics, Speech, and Signal Processing (ICASSP), pp. 2109–2112, 1989. doi.org/10.1109/ICASSP.1989.266878
Module Attributes
Wavenumber calibration values of the reference implementation, by transducer center frequency (Hz). |
|
Calibration values the reference implementation uses for any other center frequency. |
Functions
|
Remove clutter from time-delayed channel data with ADMIRE. |
|
Batched elastic-net regression with cyclic coordinate descent. |
|
Precompute the ADMIRE models for an imaging geometry. |
Classes
|
Settings of the ADMIRE model space and model fit. |
|
Precomputed ADMIRE models, as made by |
- class zea.beamform.admire.ADMIREConfig(bandwidth=0.6, alpha=0.9, lambda_scaling_factor=0.0189, max_iterations=100000, tolerance=0.1, ica=True, min_num_elements=16, pulse_multiplier=1.0, frequency_band_scaling=1.2, wavenumber_calibration='reference', cal_shift=7.75e-06, distance_offset_shift=3.85e-05, win_tune=1.0, ellipsoid_constant_1=0.0, ellipsoid_constant_2=np.float64(0.0005000000000002221), lateral_limit_offset=0.001, roi_x=(-0.5, 0.0179, 0.5), roi_z=(-0.5, 0.143, 0.5), roi_distance_offset_spacing=0.0485, roi_distance_offset_limits=(-0.0008, 0.0004), outer_x=(-1.0, 1.4228, 1.0), outer_z=(0.0, 0.0, 0.7114, 1.0, 0.0, 0.05), outer_z_offset=0.0, outer_distance_offset_spacing=0.1211, outer_distance_offset_limits=(-0.008, 0.0032), predictor_chunk_size=32768, max_cache_bytes=1073741824)[source]¶
Bases:
objectSettings of the ADMIRE model space and model fit.
The defaults are those of the reference implementation. Most users only touch the fit settings (
alpha,lambda_scaling_factor) and the aperture settings; the model-space scaling factors and calibration offsets are empirical and best left alone.Lateral and axial model-space positions are given as multiples of the lateral resolution
res_lat(estimated per window and frequency) and of the axial resolutionres_axl = 2 * res_lat. Ranges are(min, spacing, max).- Parameters:
bandwidth (
float) – Fractional bandwidth of the transmitted pulse. Sets the STFT window length and the fitted frequency band.alpha (
float) – Elastic-net mixing parameter in[0, 1]:1is the lasso,0is ridge regression.lambda_scaling_factor (
float) – The regularization strength of each fit islambda_scaling_factor * rms(y).max_iterations (
int) – Maximum number of coordinate descent sweeps.tolerance (
float) – Coordinate descent stops once the largest change of a (standardized) coefficient within a sweep, squared and divided by the number of observations, falls below this value.ica (
bool) – Replace each of the ROI and outer models by its independent components (FOBI), which shrinks each to (at most) as many predictors as there are elements. This is what makes ADMIRE tractable on a GPU;Falseuses the full models, which can hold hundreds of thousands of predictors.min_num_elements (
int) – Smallest sub-aperture that aperture growth may select.pulse_multiplier (
float) – Scales the STFT window length (one pulse full-width at half-maximum by default).frequency_band_scaling (
float) – The fitted band isf0 +- 0.5 * frequency_band_scaling * bandwidth * f0.wavenumber_calibration (
str|tuple|None) – Per-frequency wavenumber scaling."reference"looks the values up by center frequency like the reference implementation; a tuple gives them explicitly;Nonedisables calibration.cal_shift (
float) – Calibration depth offset in meters.distance_offset_shift (
float) – Calibration distance offset in meters.win_tune (
float) – Scales the half pulse length in the window amplitude model.ellipsoid_constant_1 (
float) – Pads the ROI acceptance ellipse, in meters.ellipsoid_constant_2 (
float) – Pads the ellipse that the outer model excludes, in meters.lateral_limit_offset (
float) – Extends the outer model laterally beyond the sub-aperture, in meters.roi_x (
tuple) – ROI lateral positions, in units ofres_lat.roi_z (
tuple) – ROI depth positions around the window center, in units ofres_axl.roi_distance_offset_spacing (
float) – Spacing of the ROI distance offsets, in wavelengths.roi_distance_offset_limits (
tuple) – Min and max ROI distance offsets in meters.outer_x (
tuple) – Outer-model lateral positions; min and max are multiples of the lateral limit, the spacing is in units ofres_lat.outer_z (
tuple) – Outer-model depth positions as(min_z_center, min_res_axl, spacing_res_axl, max_z_center, max_res_axl, max_z_center_extra); the minimum ismin_z_center * z_c + min_res_axl * res_axl + outer_z_offsetand the maximum(max_z_center + max_z_center_extra) * z_c + max_res_axl * res_axl.outer_z_offset (
float) – Constant added to the minimum outer-model depth, in meters.outer_distance_offset_spacing (
float) – Spacing of the outer distance offsets, in wavelengths.outer_distance_offset_limits (
tuple) – Min and max outer distance offsets in meters.predictor_chunk_size (
int) – Number of predictors generated at once, which bounds the memory use of model generation.max_cache_bytes (
int) – Models up to this size are kept in memory between the two passes of the ICA; larger ones are generated twice.
- alpha: float = 0.9¶
- bandwidth: float = 0.6¶
- cal_shift: float = 7.75e-06¶
- distance_offset_shift: float = 3.85e-05¶
- ellipsoid_constant_1: float = 0.0¶
- ellipsoid_constant_2: float = np.float64(0.0005000000000002221)¶
- frequency_band_scaling: float = 1.2¶
- ica: bool = True¶
- lambda_scaling_factor: float = 0.0189¶
- lateral_limit_offset: float = 0.001¶
- max_cache_bytes: int = 1073741824¶
- max_iterations: int = 100000¶
- min_num_elements: int = 16¶
- outer_distance_offset_limits: tuple = (-0.008, 0.0032)¶
- outer_distance_offset_spacing: float = 0.1211¶
- outer_x: tuple = (-1.0, 1.4228, 1.0)¶
- outer_z: tuple = (0.0, 0.0, 0.7114, 1.0, 0.0, 0.05)¶
- outer_z_offset: float = 0.0¶
- predictor_chunk_size: int = 32768¶
- pulse_multiplier: float = 1.0¶
- roi_distance_offset_limits: tuple = (-0.0008, 0.0004)¶
- roi_distance_offset_spacing: float = 0.0485¶
- roi_x: tuple = (-0.5, 0.0179, 0.5)¶
- roi_z: tuple = (-0.5, 0.143, 0.5)¶
- tolerance: float = 0.1¶
- wavenumber_calibration: str | tuple | None = 'reference'¶
- win_tune: float = 1.0¶
- class zea.beamform.admire.ADMIREModels(models, roi_mask, aperture_mask, window_starts, window_length, fft_length, frequency_bins, frequencies, element_positions, analytic, config=<factory>, depths=None, sound_speed=None, center_frequency=None, f_number=None)[source]¶
Bases:
objectPrecomputed ADMIRE models, as made by
generate_admire_models().There is one model per STFT window and selected frequency. Models are zero padded to a common number of rows (elements) and columns (predictors), which leaves the fit unchanged: padded columns get zero coefficients and padded rows carry no data.
- Parameters:
models (
ndarray) – Complex models of shape(n_windows, n_freqs, n_elements, n_predictors), with unit-norm columns.roi_mask (
ndarray) – Boolean mask of shape(n_windows, n_freqs, n_predictors), true for the ROI predictors used to reconstruct the signal.aperture_mask (
ndarray) – Boolean mask of shape(n_windows, n_elements)with the elements that aperture growth keeps in each window.window_starts (
ndarray) – Axial sample index where each window starts.window_length (
int) – Number of axial samples per window.fft_length (
int) – Zero-padded DFT length of a window.frequency_bins (
ndarray) – DFT bin of each selected frequency.frequencies (
ndarray) – Physical frequency of each selected bin in Hz.element_positions (
ndarray) – Lateral element positions of the sub-aperture, relative to its center, in meters.analytic (
bool) – Whether the models are made for analytic (IQ) data, where only the band around the center frequency is present, or for real RF data, where negative frequencies mirror the positive ones.config (
ADMIREConfig) – Settings used to generate the models.depths (
ndarray|None) – Depths (m) the models were generated for.sound_speed (
float|None) – Speed of sound (m/s) the models were generated for.center_frequency (
float|None) – Center frequency (Hz) the models were generated for.f_number (
float|None) – F-number of aperture growth the models were generated for.
- analytic: bool¶
- aperture_mask: ndarray¶
- center_frequency: float | None = None¶
- config: ADMIREConfig¶
- depths: ndarray | None = None¶
- element_positions: ndarray¶
- f_number: float | None = None¶
- fft_length: int¶
- frequencies: ndarray¶
- frequency_bins: ndarray¶
- models: ndarray¶
- property n_elements: int¶
Number of elements in the sub-aperture.
- property n_windows: int¶
Number of STFT windows.
- roi_mask: ndarray¶
- sound_speed: float | None = None¶
- window_length: int¶
- window_starts: ndarray¶
- zea.beamform.admire.DEFAULT_WAVENUMBER_CALIBRATION = (1.135, 0.995, 0.925, 0.905)¶
Calibration values the reference implementation uses for any other center frequency.
- zea.beamform.admire.REFERENCE_WAVENUMBER_CALIBRATION = {1818200: (1.32, 0.995, 0.835, 0.81), 2083300: (1.32, 1.0, 0.845, 0.825), 2500000: (1.315, 0.995, 0.835, 0.81), 3000000: (1.31, 0.995, 0.835, 0.805), 3125000: (1.305, 0.985, 0.825, 0.79), 3500000: (1.29, 0.99, 0.835, 0.815), 3600000: (1.315, 1.01, 0.855, 0.815), 4000000: (1.29, 0.99, 0.845, 0.82), 4500000: (1.325, 1.025, 0.87, 0.825), 5000000: (1.29, 0.995, 0.85, 0.835), 5208000: (1.145, 0.995, 0.895, 0.865), 5500000: (1.28, 0.995, 0.855, 0.845), 6500000: (1.31, 1.04, 0.89, 0.84), 7500000: (1.275, 0.975, 0.835, 0.82), 7800000: (1.295, 1.0, 0.855, 0.825), 7813000: (1.295, 1.0, 0.855, 0.825)}¶
Wavenumber calibration values of the reference implementation, by transducer center frequency (Hz). Entry
iscales the wavenumber of thei-th selected frequency of every STFT window.
- zea.beamform.admire.apply_admire(channel_data, models, window_batch_size=None)[source]¶
Remove clutter from time-delayed channel data with ADMIRE.
Port of
apply_ADMIRE_models_CPU.m: each STFT window is taken to the frequency domain, the models are fitted at every selected frequency, the signal is rebuilt from the ROI predictors only and taken back to the time domain. Frequencies outside the fitted band are removed. Samples that are not covered by a window (at the end of the axial range) are passed through unchanged.- Parameters:
channel_data (Tensor) – Delayed channel data of shape
(n_z, n_lines, n_elements, n_ch): for every image line, the sub-aperture centered on that line.n_chis1for RF data and2for IQ data, matchingmodels.analytic.models (
ADMIREModels) – Models fromgenerate_admire_models().window_batch_size (
int|None) – Number of STFT windows fitted at once, which bounds memory use. Defaults to all windows at once.
- Returns:
Decluttered channel data with the shape of
channel_data.- Return type:
Tensor
- zea.beamform.admire.elastic_net_ccd(X, y, row_mask, alpha, lambda_scaling_factor, tolerance, max_iterations)[source]¶
Batched elastic-net regression with cyclic coordinate descent.
Port of
ccd_double_precision.c. For every problem it minimizes\[\frac{1}{2N} \lVert \tilde{y} - X \beta \rVert_2^2 + \tilde{\lambda} \left( \alpha \lVert \beta \rVert_1 + \frac{1 - \alpha}{2} \lVert \beta \rVert_2^2 \right),\]with \(\tilde{y} = y / \sigma_y\) and \(\tilde{\lambda} = \lambda / \sigma_y\), where \(\lambda\) is
lambda_scaling_factortimes the RMS of \(y\), and returns \(\sigma_y \beta\). The columns ofXmust have unit norm (or be zero). Each problem stops after the first sweep in which the largest change of its coefficients falls belowtolerance, as in the reference; the loop runs until every problem has stopped.- Parameters:
X (Tensor) – Design matrices of shape
(..., N, P).y (Tensor) – Observations of shape
(..., B, N):Bright-hand sides share each design matrix.row_mask (Tensor) – Mask of shape
(..., N)with the rows that hold observations. Masked-out rows ofXandymust be zero.alpha (
float) – Elastic-net mixing parameter.lambda_scaling_factor (
float) – Regularization strength relative to the RMS ofy.tolerance (
float) – Convergence tolerance.max_iterations (
int) – Maximum number of sweeps over all coefficients.
- Returns:
Coefficients of shape
(..., B, P).- Return type:
Tensor
- zea.beamform.admire.generate_admire_models(depths, sound_speed, center_frequency, pitch, n_elements, f_number=2.0, analytic=True, start_depth=None, end_depth=None, config=None, verbose=False, n_workers=None)[source]¶
Precompute the ADMIRE models for an imaging geometry.
Port of
ADMIRE_models_generation_main.mand the functions it calls. The channel data that the models are applied to must be time-delayed (focused at every depth) and sampled at the uniformly spaceddepths.Generation is done once per geometry, on the CPU, and takes from seconds to minutes: deep windows have outer models with hundreds of thousands of predictors. The result is cached on disk (see
zea.internal.cache).- Parameters:
depths (array-like) – Uniformly spaced depths (m) of the axial samples of the delayed channel data, i.e. the z-axis of the beamforming grid.
sound_speed (
float) – Speed of sound in m/s.center_frequency (
float) – Transmit center frequency in Hz.pitch (
float) – Element pitch in meters.n_elements (
int) – Number of elements in the sub-aperture that is fitted for each image line.f_number (
float) – F-number of aperture growth; the sub-aperture is limited todepth / f_number(but at leastconfig.min_num_elementselements).0disables aperture growth.analytic (
bool) –Truefor analytic (IQ) data,Falsefor real RF data.start_depth (
float|None) – Only windows starting at or below this depth are processed. Defaults to the first depth.end_depth (
float|None) – Only windows ending at or above this depth are processed. Defaults to the last depth.config (
ADMIREConfig|None) – Model and fit settings. Defaults to the reference settings.verbose (
bool) – Show a progress bar.n_workers (
int|None) – Number of processes that generate windows in parallel. Defaults to one. Does not affect the result (up to floating-point rounding) or its cache key.
- Returns:
The models of every STFT window and selected frequency.
- Return type: