Sound-speed estimation (capstone)
Every beamformer assumes a sound speed, and every quantitative ultrasound number inherits the error of that assumption. Estimating the speed from the echoes is a delay-estimation problem (Module 11) sitting inside an inverse problem (Module 13), solved with the beamformer itself as the forward model (Modules 07, 14, 25). This capstone builds the estimators from the global focus-optimal speed, through the average-to-local inversion of layered media and echo-mode tomography (CUTE), to differentiable beamforming, and closes with the error budget that decides whether a liver measurement can separate healthy from steatotic tissue.
You will be able to
- Compute the focusing tolerance on sound speed for a given F-number, depth and frequency, and say what a 1 % error does to phase, depth and coherence
- Explain why a focus-quality maximizer returns an average speed (the RMS speed of seismology, not the harmonic mean), and invert averages to local speeds with Dix's formula, straight-ray differencing or regularized least squares, with their noise amplification
- Derive the CUTE measurement (echo phase shifts between steered acquisitions), its wrapping limit, the phase jitter of correlated speckle, and the difference between transmit-only and common-mid-angle data
- Set up limited-angle sound-speed tomography as \(\mathbf{d} = \mathbf{A}\,\Delta\mathbf{s} + \mathbf{n}\), read its resolution matrix, and separate noise, regularization and forward-model errors
- Recognize differentiable-beamforming autofocus as nonlinear tomography, predict where its losses have local minima, and place deep-learning and full-wave methods on the same map
- Write an error budget (CRLB, calibration, layer bias, model error) for a clinical liver sound-speed measurement and compare it with the 10–40 m/s effects that matter
Assumes
- Module 07 · Random vectors, covariance & correlation: coherence and the van Cittert–Zernike theorem; Module 11 · Correlation & time-delay estimation: delay estimation and its jitter
- Module 12 · Estimation theory and the Cramér–Rao bound; Module 13 · Inverse problems and regularization: Tikhonov, resolution matrices and Section 13.8 on limited-angle SoS tomography; Module 14 · Optimization & automatic differentiation: autofocus (Section 14.5) and cycle skipping (Section 14.4)
- Module 25 · Adaptive and coherence-based beamforming: coherence factor and SLSC; Module 23 · Beam patterns, k-space and compounding: plane-wave compounding
32.1Why sound speed matters: focus, geometry and a biomarker
Soft tissues span roughly 1450 m/s (fat) to 1600 m/s (muscle, healthy liver), a −6 % to +4 % band around the 1540 m/s that every scanner assumes. A wrong speed does three separate things. It defocuses: the receive delays have the wrong curvature, so the aperture sums out of phase. It misplaces: depth is computed as \(\hat c\,t/2\). And it hides a biomarker: fat lowers the sound speed of liver, so the speed itself is a quantitative measure of steatosis, and every downstream QUS estimate (attenuation, backscatter, Module 27) is computed from images formed with the assumed value.
Start with the defocus. Place the pixel by its two-way time, as every scanner does, so the on-axis delay is always right. A receive element at lateral offset \(x\) then sees a residual delay set by the error in the wavefront curvature. With \(\hat c = c + \Delta c\), depth \(\hat z = \hat c t_a\) (\(t_a\) the one-way apex time) and \(x \ll z\):
- \(\delta\tau(x)\)
- receive delay error of the element at offset \(x\) after the pixel is placed at the correct two-way time, s
- \(c,\ \hat c,\ \Delta c\)
- true, assumed and error of the sound speed, m/s
- \(z,\ \hat z\)
- true and displayed depth of the pixel, m (\(\hat z/z = \hat c/c\))
- \(F\)
- receive F-number \(z/D\), with \(D = 2X\) the active aperture
- \(\lambda,\ f_0\)
- wavelength \(c/f_0\) and centre frequency
The geometry and the parameterization follow from the same travel times. Displayed depth scales as \(\hat z = (\hat c/c)\,z\): 1 % of speed is 0.3 mm at 30 mm, larger than the axial resolution at 5 MHz. And every travel time is linear in slowness \(s = 1/c\), not in speed, which is why all the inversions below are written for the slowness deviation:
- \(\Delta s\)
- slowness deviation from the beamforming slowness, ns/mm (10−6 s/m)
- \(c_0\)
- sound speed assumed by the beamformer
- \(c\)
- local sound speed of the medium, m/s
The biomarker. Imbault et al. (Phys. Med. Biol., 2017) estimated local liver speed in 17 patients and found 1492–1604 m/s across MRI proton-density fat fractions of 2–17 %, with an area under the ROC curve of 0.952 against biopsy and cut-offs of 1541 m/s (PDFF 5 %) and 1555 m/s (biopsy 10 %). Those numbers set the scale for everything in this module: a useful estimator must resolve about 10 m/s in a liver that sits under 10–30 mm of fat and muscle at 1450–1580 m/s. The overlying layers bias any average by tens of m/s (Section 32.3), so the hard part of liver sound speed is not precision, it is locality.
| Family | Measures | Output | Key assumption | Where in this module |
|---|---|---|---|---|
| Focus-quality maximization (CF, coherence, brightness, sharpness) | focus metric versus assumed \(\hat c\) | one average speed per region | homogeneous medium above the region | 32.2, Demo 32.1 |
| Wavefront curvature (Anderson and Trahey, 1998) | arrival-time profile across the aperture | average speed to a depth | hyperbolic moveout | 32.2, 32.7 |
| Average-to-local inversion (Jakovljevic et al., 2018) | averages at many depths | local speed per layer or depth | layered medium, straight vertical rays | 32.3, Demo 32.2 |
| Echo-mode tomography: CUTE and spatial-domain methods | echo phase shifts between steered acquisitions | 2D map of \(\Delta s\) | straight rays, linearized, limited angle | 32.4–32.5, Demos 32.3–32.4 |
| Differentiable beamforming autofocus | gradient of a focus or phase loss | 2D map | differentiable forward model (usually straight rays) | 32.6, Demo 32.5 |
| Learned and full-wave inversion | channel data to map, or wave-equation migration velocity analysis | 2D map | training distribution, or the wave equation | 32.6 |
32.2Global sound speed by focus-quality maximization, and which average it returns
The oldest estimators sweep \(\hat c\), beamform, and keep the speed that maximizes a focus metric. Module 07 showed why that works: the van Cittert–Zernike theorem makes the aperture-domain coherence of speckle peak when the delays are right, and Module 14 turned the sweep into gradient ascent. The usual metrics, all evaluated on delayed channel signals \(s_i\) of a pixel or a region tied to two-way time:
- \(s_i(\hat c)\)
- complex (IQ) signal of element \(i\) after delaying with speed \(\hat c\)
- \(\mathrm{CF}\)
- coherence factor, 1 for perfectly aligned equal signals, ≈ 1/N for noise (Module 25)
- \(R_1\)
- lag-one spatial coherence
- \(B\)
- speckle brightness (energy) of a region
- \(\hat c\)
- trial (assumed) sound speed used for the delays, m/s
- \(i,\ N\)
- element index and number of elements
- \(\mathrm{Re},\ (\cdot)^{*}\)
- real part, complex conjugate
- \(\mathrm{ROI}\)
- region of interest (set of pixels summed)
Anderson and Trahey (J. Acoust. Soc. Am., 1998) estimated the speed more directly from the arrival-time profile of the echoes across the aperture: in a homogeneous medium the profile is a hyperbola whose curvature fixes \(\hat c\) once the apex time is known. Both families answer the same question, "which homogeneous speed best explains the wavefront?", and both are exact only for a homogeneous medium. Under a fat layer they return an average. Which one?
Write the vertical one-way time through layers of thickness \(d_i\) and speed \(c_i\) as \(T = \sum_i \Delta T_i\), \(\Delta T_i = d_i/c_i\), and the time weights \(w_i = \Delta T_i/T\). Two averages are natural:
- \(V_h\)
- harmonic (time-average) speed: depth over one-way time, m/s
- \(V_{\mathrm{rms}}\)
- root-mean-square speed, time-weighted, m/s
- \(w_i\)
- fraction of the vertical travel time spent in layer \(i\)
- \(\operatorname{Var}_w(c)\)
- time-weighted variance of the layer speeds
- \(z,\ T\)
- depth (m) and one-way travel time (s)
- \(c_i\)
- sound speed of layer \(i\), m/s
- \(w_1,\ w_2,\ c_1,\ c_2\)
- time fractions and speeds of the two layers
m32_global_sos_focus.m checks this on simulated channel data with Snell refraction: the CF-optimal speed lands 0.6–1.0 m/s above \(V_{\mathrm{rms}}\) at every depth from 15 to 50 mm (1547.1 m/s at 40 mm), while the liver below is at 1580. Demo 32.1 runs the same physics on a point target and shows the residual phase across the aperture: at the optimum the quadratic part vanishes and only the non-hyperbolic (quartic) moveout of the layered medium is left.
Focus quality versus assumed speed under a fat layer: average, not local
SimulationPoint target on axis under a flat fat layer. True receive times by Snell ray tracing (bisection on the ray parameter, JS); 0° plane-wave transmit (vertical, exact through flat layers). Beamformer: homogeneous \(\hat c\), pixel tied to the two-way apex time. Each element contributes a Gaussian pulse (60 % bandwidth) at its residual delay; CF (32.3) of those signals. Same physics as m32_global_sos_focus.m without noise or the ROI average. No attenuation, no element directivity.32.3From average to local: layered media, Dix and the price of differentiation
A focus maximizer applied at many depths returns an average profile \(\bar c(z)\). The local speed is hidden in how that average changes with depth. In the vertical straight-ray model the one-way time to depth \(z\) is the integral of slowness, and the measured average is \(\bar c(z) = z/T(z)\). Written in slowness, the relation is linear, and inverting it is a derivative:
- \(\bar s(z) = 1/\bar c(z)\)
- average slowness from the surface to depth \(z\), s/m
- \(s(z)\)
- local slowness at depth \(z\)
- \(\Delta z\)
- spacing of two average measurements, m
- \(\sigma_{\bar c},\ \sigma_{c,\mathrm{loc}}\)
- standard deviation of each average and of the local estimate, m/s (independent errors, \(c_{\mathrm{loc}} \approx \bar c\))
- \(z\prime\)
- integration variable (depth), m
- \(k\)
- index of the measurement depth \(z_k\)
- \(z_k,\ \bar s_k\)
- depth and average slowness at measurement \(k\)
- \(\bar c\)
- average speed \(1/\bar s\), m/s
Seismologists met the same problem with stacking velocities, which are RMS averages (32.4). Dix's interval formula inverts them exactly for flat layers:
- \(c_{\mathrm{int},k}\)
- interval (local) speed between reflectors \(k-1\) and \(k\), m/s
- \(T_k\)
- one-way vertical time to reflector \(k\), from the echo time
- \(V_{\mathrm{rms},k},\ \hat c_k\)
- focus-optimal (RMS) speed measured at reflector \(k\)
- \(z_k\)
- depth of reflector \(k\), m
- \(k\)
- reflector index
Two ways out of the noise. Regularization (Module 13) trades resolution for precision: penalize the first difference of the local slowness and pick \(\lambda\) by the discrepancy principle, \(\lVert \mathbf{W}(\mathbf{A}\mathbf{s} - \mathbf{b})\rVert^{2} \approx m\). A layer prior uses the interfaces visible in the B-mode image and estimates one speed per layer, which turns the ill-posed derivative into a well-posed least-squares problem with three unknowns:
- \(\mathbf{A}\)
- cumulative-sum operator: \(A_{kj} = \Delta z\) for cells \(j\) above measurement depth \(z_k\)
- \(\mathbf{b}\)
- data \(b_k = z_k/\bar c_k\), s
- \(\mathbf{W}\)
- whitening, \(1/(z_k\sigma_{\bar s})\) on the diagonal
- \(\mathbf{D}\)
- first-difference matrix
- \(\mathbf{P}\)
- cell-to-layer indicator matrix (interfaces from the image)
- \(\mathbf{s}\)
- slowness per cell, s/m
- \(\hat{\mathbf{s}}_\lambda,\ \hat{\mathbf{s}}_{\mathrm{layer}}\)
- regularized and layer-constrained slowness estimates
- \(\lambda\)
- regularization weight (balance of data fit and smoothness)
- \(\lVert\cdot\rVert,\ \arg\min\)
- Euclidean norm, minimizing argument
- \(\mathbf{B}\)
- \(\mathbf{W}\mathbf{A}\mathbf{P}\), the weighted forward operator on layers
- \((\cdot)^{T}\)
- transpose
This is the logic of Jakovljevic et al. (J. Acoust. Soc. Am., 2018): Anderson-type averages first, then a model relating local speeds to path averages, solved by gradient descent. In two-layer phantoms and simulations their local estimates had biases below 6.2 m/s where the matched averages were biased by up to 66 m/s, at the cost of a larger standard deviation that a 5 × 5 mm region brought below 7 m/s. Ali and Dahl later moved the same idea to travel-time tomography from average speeds (IEEE IUS 2019), and Brevett, Sanabria, Ali and Dahl to common-midpoint gathers of non-beamformed data (IEEE IUS 2022).
Reporting the focus-optimal speed of a deep liver ROI as "the liver speed". Under 10 mm of fat (1450 over 1580 m/s) it reads about 45, 34, 22 and 17 m/s low (\(V_{\mathrm{rms}}\)) at 30, 40, 60 and 80 mm, more than the 14 m/s between the two Imbault cut-offs. A global estimate is a property of the path, not of the tissue at the end of it.
Average-to-local inversion: naive differencing, Tikhonov and a layer prior on the same noisy data
SimulationVertical straight-ray model (32.5) on 60 cells of 1 mm; averages \(\bar c(z_k)\) from 4 mm down, every 1–4 mm, with Gaussian noise of the set standard deviation (seeded, JS). Linear least-squares solutions of (32.7) by Cholesky. Same model as m32_layered_inversion.m (different random numbers, so the readouts differ slightly). No refraction, no lateral variation, and the averages are taken as the harmonic \(z/T\), not \(V_{\mathrm{rms}}\).32.4Echo-mode tomography I: what CUTE measures
Averages along vertical paths cannot see lateral structure. Jaeger and colleagues (Ultrasound Med. Biol., 2015) added angle diversity with ordinary pulse-echo hardware: beamform the same region with \(c_0\) from several steered plane-wave transmits, and compare the phase of the complex images pixel by pixel. If the tissue is homogeneous at \(c_0\), every steered image of a given speckle pixel has the same phase. If not, each transmit direction accumulates a different travel-time error on its way to the pixel, and the echo phase shifts. In the straight-ray, first-order model (Section 13.8 built its linear algebra):
- \(L_\theta(x,z)\)
- travel-time error accumulated along the straight path from pixel \((x,z)\) to the array at angle \(\theta\) from vertical, s
- \(\Delta s\)
- slowness deviation (32.2)
- \(\Delta\tau_\theta\)
- echo delay shift between the image transmitted at \(\theta\) and at 0°, with the receive beamforming kept fixed (it cancels), s
- \(\Delta\phi\)
- measured phase shift at the centre frequency \(f_0\), rad
- \(x,\ z,\ z\prime\)
- lateral position, depth of the pixel and integration depth, m
- \(\theta\)
- transmit steering angle, rad
- \(\Delta\tau\)
- delay shift, s
- \(f_0\)
- centre frequency, Hz
Two practical limits follow at once. Wrapping: a phase is known modulo 2π, so \(\lvert\Delta\tau\rvert\) must stay below \(1/(2f_0)\) = 100 ns at 5 MHz. CUTE therefore measures between small angle steps and accumulates: a 2° step reaches only 56 ns (1.8 rad) for the same inclusion. Decorrelation: the phase of a speckle pixel is random, and only its change is meaningful if the two images contain the same speckle. Steering the transmit alone changes the speckle pattern. Stähli et al. (Ultrasonics, 2020) therefore paired transmit angle \(\varphi\) and receive angle \(\psi\) and compared only pairs that share the mid-angle \(\gamma = (\varphi + \psi)/2\), whose isochrones (and speckle) stay in place:
- \(\varphi,\ \psi\)
- transmit and receive steering angles
- \(\gamma\)
- common mid-angle
- \(S\)
- vertical one-way delay error of a laterally uniform layer, s
- \(d_{\gamma}\)
- difference in travel-time error between two transmit–receive angle pairs with the same mid-angle \(\gamma\), s
- \(n,\ n\prime,\ m,\ m\prime\)
- indices of the transmit and receive angles of the two pairs
- \(L\)
- travel-time error along one ray, as in (32.8), s
- \(\theta\)
- steering angle, rad
- \(\sec\)
- secant, \(1/\cos\)
The noise of a phase-shift datum is the phase of a sample correlation. For \(N\) independent speckle samples in the kernel and a correlation coefficient \(\rho\) between the two images, the large-\(N\) result (the Cramér–Rao bound of interferometric phase, Module 12) is
- \(a_{1,k},\ a_{2,k}\)
- complex pixel values of the two beamformed images in the kernel
- \(N\)
- number of independent speckle cells in the kernel
- \(\rho\)
- correlation coefficient between the two images (speckle decorrelation plus noise)
- \(\sigma_\phi,\ \sigma_\tau\)
- phase and delay jitter of one datum
- \(\hat\phi\)
- estimated phase shift between the two images, rad
- \(k\)
- pixel index in the kernel
- \(\arg\)
- phase angle, rad
- \((\cdot)^{*}\)
- complex conjugate
- \(f_0\)
- centre frequency, Hz
Put the pieces together for the hardest case: the speed of a 5 mm layer from common-mid-angle data at ±20° with 0.92 ns jitter (ρ = 0.95, N = 64) is uncertain by 2.0 ns/mm, i.e. 5 m/s, from a single pair of pixel data (the layer delay \(S\) is the datum just below the layer minus the datum just above it, so \(\sqrt2 \times 0.92\) ns divided by \(2(\sec 20° - 1) \times 5\) mm). Averaging laterally helps; the axial blur of Section 32.5 does not. Stähli et al. also showed that a quantitative forward model needs a second correction: the misfocused echo is reconstructed at a shifted position, which adds a phase shift of its own. With both features their liver-phantom reconstructions came within a few m/s of the through-transmission values (standard error 2.5–10 m/s) and a volunteer liver read 1564 ± 4 m/s.
CUTE phase-shift maps: inclusion, fat layer, steering angle, wrapping and speckle jitter
Approx. modelStraight-ray, first-order delay model (32.8)–(32.9) on a 0.25 mm grid (38.4 × 40 mm), marched row by row in JS with linear interpolation, smooth inclusion edge (0.3 mm). Optional jitter: independent Gaussian delay noise per pixel with \(\sigma_\tau\) from (32.10). No refraction, no echo-position shift, no beamforming; same model as m32_cute_phase_shift.m.32.5Echo-mode tomography II: inversion, limited angle and the forward model
Stack every phase-shift datum of every pixel into one linear system. Each row of \(\mathbf{A}\) is a difference of straight-ray weight vectors (path lengths through the cells of the slowness grid), and the inversion is the general-form Tikhonov problem of Module 13 with a gradient penalty:
- \(\mathbf{d}\)
- all delay-shift data (32.8)–(32.9), ns
- \(\mathbf{A}\)
- differences of ray-weight rows, mm (path length per cell)
- \(\Delta\mathbf{s}\)
- slowness deviation per cell, ns/mm
- \(\mathbf{G}\)
- lateral and axial first differences between neighbouring cells
- \(\mathbf{R}\)
- resolution matrix: row \(k\) is the point-spread function of the reconstruction at cell \(k\); \(\operatorname{tr}\mathbf{R}\) counts the resolved degrees of freedom
- \(\mathbf{n}\)
- measurement noise, ns
- \(\Delta\hat{\mathbf{s}}\)
- regularized estimate of the slowness deviation
- \(\lambda\)
- regularization weight
- \(\mathbb{E}\)
- expectation over the noise
- \((\cdot)^{T},\ (\cdot)^{-1}\)
- transpose, matrix inverse
Limited angle. Rays within ±θmax of vertical measure, by the Fourier-slice theorem, only a wedge of spatial frequencies around the \(k_x\) axis (Section 13.8). Everything near \(k_z\), horizontal edges and the axial profile, sits in the missing cone. The resolution kernels are therefore elongated in depth and get worse with depth: m32_sos_tomography.m (θmax = 25°, 7 angles, 2.4 mm cells) finds axial/lateral FWHM of 2.5/2.4, 2.6/2.4 and 3.4/2.4 mm at 9, 19 and 31 mm for transmit-only data. Layers and the absolute level are in the same blind spot: a constant \(\Delta s_0\) shifts every datum by only \(\Delta s_0 z(\sec\theta - 1)\), so the mean speed must come from somewhere else. That is why CUTE reconstructions are run with an a priori speed and why Stähli et al. (2020, Figs. 4–6 of the preprint) and Jaeger et al. (2022, Figs. 9–10) show their maps for several a priori values.
Forward-model error dominates noise. The same script separates the error sources by running each design twice. With data generated by the cell model itself plus 2 ns noise (noise and regularization only) the RMSE is 3.8 m/s for transmit-only and 1.9 m/s for common mid-angle. With noise-free data from fine straight rays through a smooth truth (discretization and regularization only) it is 22.0 and 30.8 m/s. The model, not the noise, is the error budget, and adding more data rows does not fix it. In the ray model a common-mid-angle row \((W_i + W_j) - (W_{i-1} + W_{j+1})\) is exactly a combination of transmit-only rows of the same pixel (the script verifies a residual of 5×10⁻¹⁵): CMA adds no ray information. Its benefit lives outside this model, in the speckle correlation of (32.10) and the echo-position term that Stähli et al. added. Spatial-domain formulations of the same reconstruction (Sanabria et al., Phys. Med. Biol., 2018) and learned forward models are attempts to shrink exactly this model error.
Echo-mode SoS tomography is transmission tomography with the sources and detectors on the same side, so every ray is nearly vertical. It sees lateral changes well, axial changes poorly and uniform offsets hardly at all, which is the opposite of what a liver protocol needs (a layered abdominal wall over a uniform organ). Every successful method adds what the rays cannot give: an a priori mean, interfaces from the image, or a better forward model.
Limited-angle SoS tomography: reconstruction and resolution-matrix kernels for two acquisition designs
Simulation16 × 12 cells of 2.4 mm (x ±19.2 mm, z 2–30.8 mm) under a 38.4 mm array. Data at every cell centre from straight-ray delays at K angles in ±θmax (rays must reach the aperture); transmit-only = adjacent-angle differences, CMA = adjacent pairs with a common mid-angle. "Cell-consistent" data use the inversion's own ray weights (0.3 mm steps, nearest cell); "fine-ray" data integrate the smooth truth with 0.1 mm steps (model error). Tikhonov with a gradient penalty (32.11), Cholesky in JS. Smaller grid than m32_sos_tomography.m (16 × 14), same construction.32.6Autofocus as optimization: differentiable beamforming, learned and full-wave inversion
Module 14 climbed a single \(\hat c\) by gradient ascent on a focus metric. Differentiable beamforming does the same for a whole map. Simson et al. (MICCAI 2023) wrote delay-and-sum in an automatic-differentiation framework so that a loss computed on the beamformed data could be differentiated with respect to every cell of a sound-speed map, and optimized phase-shift, speckle-brightness and coherence losses by gradient descent. With straight rays, the chain rule shows what that gradient is:
- \(\tau_i\)
- beamforming delay of channel/path \(i\) (transmit plus receive) for a pixel, s
- \(\ell_{ij}\)
- length of path \(i\) in cell \(j\), m (the ray weights of (32.11))
- \(\mathcal{L}\)
- scalar loss on the beamformed data (phase error, brightness, coherence)
- \(\nabla_{\tau}\mathcal{L}\)
- sensitivity of the loss to each delay, computed by automatic differentiation through the interpolator
- \(s_j\)
- slowness of cell \(j\), s/m
- \(\mathbf{A}\)
- ray-weight matrix with entries \(\ell_{ij}\), as in (32.11)
- \(\partial\)
- partial derivative
- \(i,\ j\)
- path index and cell index
The later formulation (Simson et al., arXiv:2410.03008) replaced the loss with a common-midpoint phase error, the mean absolute phase of correlations between lag-1 common-midpoint subaperture pairs, keeping only pairs with correlation above 0.7, plus total-variation regularization of the map:
- \(\hat\Gamma^{\mathrm{CM}}_{pq}(\mathbf{x}_f)\)
- complex correlation at pixel \(\mathbf{x}_f\) between the images of subaperture pairs \(p\) and \(q\) that share a common midpoint
- \(N_x,\ N_{\mathrm{CM}}\)
- number of pixels and of common-midpoint pairs
- \(\alpha\)
- weight of the total-variation penalty
- \(\angle\)
- phase angle, rad
- \(\mathrm{TV}\)
- total variation of the sound-speed map
- \(c(\mathbf{x})\)
- sound-speed map being optimized, m/s
- \(\mathrm{FOV}\)
- field of view (set of pixels \(\mathbf{x}_f\))
- \(\mathcal{L}_{\mathrm{CMPE}}\)
- common-midpoint phase-error loss, rad
Why phase losses have local minima. A phase is periodic in delay with period \(1/f_0\). Once a residual delay difference exceeds half a period the wrapped phase points the wrong way, and gradient descent locks onto a wrong cycle, the cycle skipping of Section 14.4. The ways out are the ones seismology uses: start from a good global estimate (Section 32.2), compare only nearby (lag-1) and well-correlated signals, go from low to high frequency, or use envelope and coherence losses that are smooth but less sharp. Demo 32.5 maps the loss over a two-layer model and lets you start the descent anywhere.
Learned inversion. Feigin, Freedman and Anthony (IEEE Trans. Biomed. Eng., 2020; preprint 2018) trained a fully convolutional network to map raw channel data of three plane waves directly to a sound-speed map. It was trained on 6,026 k-Wave simulations of random elliptical inclusions (1300–1800 m/s) in speckle and reached 20.5 m/s RMSE on simulated test data; on a phantom and in vivo the results were qualitative. The forward model is now implicit in the training set, so the model error of Section 32.5 becomes a domain gap that no regularizer can see.
Full-wave inversion. Straight rays ignore refraction and diffraction, which are not small at fat–muscle interfaces. Geophysics solved the same problem with wave-equation migration velocity analysis; Ali's thesis (Stanford, 2021) laid the groundwork for it in pulse-echo ultrasound. On the IEEE IUS 2026 QUASOS challenge, which scored bias, variance, lesion detectability and robustness to near-field aberration on phantom and simulated RF data, the published final sound-speed scores (lower is better) put R. Ali (Rochester) first at 22.6 and the Bern CUTE group (M. Jaeger) ninth at 72.5 among 11 entries.
Differentiable autofocus on a two-layer model: loss landscape, gradient path and local minima
SimulationFour point targets on axis at 20, 30, 40 and 50 mm under a flat fat layer of known thickness; true receive times by Snell ray tracing (JS). The beamformer's model is two layers with unknown speeds \((\hat c_1, \hat c_2)\) and straight rays, pixel tied to the two-way apex time, as in a straight-ray differentiable beamformer. Losses: 1 − mean CF (32.3), or the mean absolute wrapped phase difference between elements \(\ell\) apart, normalized by π (a simplified stand-in for phase-error losses such as (32.13), not CMPE itself). Gradient by central differences; normalized gradient descent with a decaying step.32.7Error budget, validation and clinical numbers
How precise can a sound-speed estimate be? Take the cleanest case: a wavefront-curvature fit (Anderson and Trahey's idea) to receive arrival times \(t_i = t_a + (\sqrt{z^{2}+x_i^{2}} - z)/c\) with \(z = c\,t_a\), independent per-element jitter \(\sigma_t\) (whose own bound, set by SNR, bandwidth and decorrelation, is the delay CRLB of Modules 11 and 12), and an unknown common offset. The Fisher information gives, in the parabolic limit,
- \(\sigma_t\)
- per-element arrival-time jitter, s
- \(N,\ X\)
- number of elements and half-aperture, uniform spacing; \(\operatorname{sd}(x^{2}) = X^{2}\sqrt{4/45}\) for a continuous uniform aperture
- \(F\)
- F-number \(z/(2X)\)
- \(b_{\mathrm{cal}}\)
- bias from a systematic delay error that grows quadratically to \(\delta\) at the aperture edge (lens, element delay calibration), m/s
- \(c,\ z\)
- sound speed (m/s) and depth (m)
- \(x_i\)
- lateral position of element \(i\) in the aperture, m
- \(\operatorname{sd}\)
- standard deviation over the aperture
- \(\delta\)
- systematic delay error at the aperture edge, s
- \(\sigma_c\)
- standard deviation of the speed estimate, m/s
The precision floor is not the problem. Averaging over a region of a few hundred independent kernels pushes the random part well below 1 m/s, and the systematic terms take over. The complete budget for a liver measurement adds, roughly in decreasing order:
- \(b_{\mathrm{model}}\)
- forward-model error (straight rays, no echo-position term, discretization), m/s
- \(b_{\mathrm{reg}}\)
- regularization and prior bias (a priori mean, smoothing across interfaces)
- \(\varepsilon,\ M\)
- random error and number of independent kernels averaged
- \(\hat c,\ c_{\mathrm{liver}}\)
- estimated and true liver sound speed, m/s
- \(V_{\mathrm{rms}}\)
- as in (32.4), m/s
- \(b_{\mathrm{cal}}\)
- as in (32.14), m/s
- \(\lambda\)
- regularization weight, as in (32.7)
- \(\sigma_c\)
- standard deviation of one kernel’s estimate, m/s
Validation. Phantom references come from through-transmission time of flight, quoted at ±5 m/s by Stähli et al. (2020) and Jaeger et al. (2022), so a phantom study cannot resolve errors much below that. Jaeger et al. (Phys. Med. Biol., 2022) carried CUTE to a convex probe (C6-1X, 3 MHz) for liver depths: in a four-layer abdominal phantom the liver agreed with its nominal value, axial resolution was about 10 mm at 30 mm depth, and in a volunteer the superficial liver read about 1580 m/s, while below about 50 mm the estimate deteriorated and, in vivo, varied by up to 100 m/s with the a priori speed below 60 mm. QUASOS (IEEE IUS 2026) added the first shared benchmark with phantom and simulated RF data, with and without near-field aberrators.
Sound speed is upstream of everything quantitative. Attenuation and backscatter estimates (Module 27) are computed on images formed with \(c_0\); shear-wave tracking (Module 30) and ULM localization (Module 31) inherit the depth scaling \(\hat c/c\) and the defocus; and aberration correction (Module 33) is, in its distributed form, a sound-speed map turned back into delays. A 1 % speed error is a 0.3 mm depth error at 30 mm, larger than the localization precision ULM claims.
Error budget of a liver sound-speed measurement
Approx. modelRandom term: parabolic CRLB (32.14) with the discrete-aperture spread, divided by √M for M independent kernels; local estimates by differencing over Δz multiply it by √2 z/Δz (32.5). Calibration: quadratic edge error \(\delta\), bias \(c^{2}z\delta/X^{2}\). Layer bias of an average: \(V_{\mathrm{rms}}\) of (32.4) minus the liver speed. Model error: entered by hand (no formula exists; Section 32.5 suggests tens of m/s for straight-ray tomography). Biases are added by magnitude (worst case), the random term in quadrature; the calibration bias is applied unchanged to both estimates.32.8Visual summary
Thirteen questions a sound-speed expert answers in five seconds. Each figure is computed from the formula or model named in its badge.
32.9How experts think about it
A sound-speed expert keeps three questions apart. What does the datum measure (a curvature, a phase shift between two paths, a focus metric), and along which paths? Which average, or which linear combination of the local slowness, does that make it? And what blind spots does the path geometry leave (layers, the mean, axial detail), so what prior or extra physics must fill them? Precision is rarely the limit; locality, calibration and the forward model are.
With the pixel tied to two-way time the on-axis delay is always right; the edge element is off by \((\Delta c/c)X^{2}/(zc)\) (32.1). Setting the edge phase below π/4 gives the tolerance, which scales as F². The depth error \((\Delta c/c)z\) is linear and only matters for geometry and for registration with other modalities.
\(\tau = \int s\,dl\) is linear in \(s\), so every inversion in this module (layered, tomographic, gradient) is a linear or linearized problem in \(\Delta s\) (32.2). Converting back with \(\Delta c \approx -c_0^{2}\Delta s\) costs \(\Delta c^{2}/c\), 1.0 m/s (2.5 % of the correction) at 40 m/s; averaging speeds instead of slownesses biases means by \(\operatorname{Var}(c)/c\).
Small-offset moveout under flat layers is hyperbolic with \(V_{\mathrm{rms}}\) (Dix), so CF, coherence, brightness and curvature fits all return it (32.4). In m32_global_sos_focus.m the CF optimum sits 0.6–1.0 m/s above \(V_{\mathrm{rms}}\) at every depth; Demo 32.1 finds 0.1–0.3 m/s for a single point.
A quadratic phase across a uniform aperture gives \(\mathrm{CF} = \lvert\langle e^{j\Phi u^{2}}\rangle\rvert^{2}\) (32.3). The half-maximum sits at an edge phase of 2.73 rad, tens of m/s from the peak, while the peak position can be read to a fraction of a m/s with parabolic interpolation. Width tracks F² and frequency, not tissue.
The local slowness is the derivative of \(z\bar s(z)\) (32.5); differencing two averages of independent error multiplies it by \(\sqrt{z_k^{2} + z_{k-1}^{2}}/\Delta z\). m32_layered_inversion.m: 85.8 predicted, 87.1 by Monte Carlo at 30 mm. Every local estimator pays this, explicitly or through its regularizer.
Applying the straight-ray rule \(\Delta z/\Delta T\) to focus-optimal (RMS) speeds mixes two definitions; Dix's \(\sqrt{\Delta(V^{2}T)/\Delta T}\) (32.6) is the consistent inverse. On noise-free CF optima the difference is 0.4–1.9 m/s: negligible against noise, not against a claimed 1 m/s accuracy.
Interfaces from the B-mode image turn the derivative into a three-unknown least-squares fit (32.7): 1449.3 ± 0.8, 1587.6 ± 2.5, 1548.9 ± 0.7 m/s in m32_layered_inversion.m. The error bars describe noise only; an unmodelled lesion moves the layer value while the error bar stays small (figure: noise-free fit of a liver containing a 10 mm lesion).
The CUTE datum is a phase (32.8), so only \(\lvert\Delta\tau\rvert < 1/(2f_0)\) is unambiguous. A +40 m/s, 5 mm inclusion produces 169 ns between 0° and 15° but 56 ns for a 2° step (m32_cute_phase_shift.m). Stähli et al. used 2° steps and accumulated over 10°.
The bound of (32.10) falls as \(1/\sqrt N\) but as \(\sqrt{1-\rho^{2}}\) near ρ = 1: from 0.9 to 0.99 is a factor 3.4, worth 12 times more samples. That is the reason for common-mid-angle and common-midpoint pairings: they keep the speckle in place.
A laterally uniform layer, or a constant offset of \(\Delta s\), shifts every steered path almost equally, so the differences that CUTE measures see only the \(\sec\theta - 1\) excess (32.9). 4 mm of fat delays everything by 161 ns and moves the 15° datum by 5.7 ns. Reconstructions need an a priori mean or an independent global estimate.
\(\mathbf{R} = (\mathbf{A}^{T}\mathbf{A} + \lambda^{2}\mathbf{G}^{T}\mathbf{G})^{-1}\mathbf{A}^{T}\mathbf{A}\) (32.11) needs only the geometry. Its rows show the missing cone: m32_sos_tomography.m finds axial FWHM of 2.5, 2.6, 3.4 mm (transmit-only) and 2.6, 2.9, 4.2 mm (CMA) at 9, 19, 31 mm, lateral fixed at the cell size.
Running the same inversion on data from its own cell model and on fine-ray data through a smooth truth separates the two (m32_sos_tomography.m, transmit-only / CMA). Removing the noise altogether moves the fine-ray RMSE by 0.2 m/s (22.2 to 22.0); refining the forward model (echo position, refraction, discretization) is what moves the number. That is the argument of Stähli et al. (2020).
With straight rays the delay of each path is \(\sum_j \ell_{ij}s_j\), so the gradient of any loss is a back-projection of delay sensitivities along those rays (32.12). Each step is a nonlinear Landweber step on the same \(\mathbf{A}\) as CUTE; it inherits the missing cone and needs the same priors (TV in the CMPE formulation).
A wrapped phase is periodic in the delay residual, so the loss has secondary minima spaced by one period (Section 14.4). The figure is the edge lag-ℓ phase loss for a homogeneous error at 30 mm, 5 MHz, 30 mm aperture: longer lags sharpen the main minimum and bring the side minima closer. Initialize with a coherence-based global speed and use lag-1, well-correlated pairs.
The curvature CRLB (32.14) is 1.69 m/s for one kernel at 30 mm (Monte Carlo 1.68); a few hundred independent kernels bring it to 0.1 m/s. At fixed pitch it falls about as \(N^{-2.5}\) because the curvature grows as \(X^{2}\). Quote a CRLB only next to the biases of (32.15).
A systematic delay error that grows to δ at the aperture edge is indistinguishable from a curvature change (32.14). A lens whose speed or thickness differs from the nominal one produces exactly such an error, and it does not average out. Lens speed and thickness belong in the estimated parameters or in a calibration step.
Feigin et al. (2020) mapped three plane waves of raw channel data to a speed map and reached 20.5 m/s RMSE on simulated test data; in vivo the results were qualitative. The forward model moved from the equations into the training distribution, so model error becomes domain gap: random ellipses in speckle are not an abdominal wall.
32.10Cheat sheet
| Concept | Formula | Ultrasound use |
|---|---|---|
| Receive defocus from a speed error | \(\delta\tau(x) \approx (\Delta c/c)\,x^{2}/(zc)\) | 104 ns at the edge of 38.4 mm, 30 mm, 20 m/s |
| Focusing tolerance | \(\lvert\Delta c\rvert < c^{2}F^{2}/(2f_0 z)\) | 7.9 m/s at F/1, 30 mm, 5 MHz; scales as F² |
| Depth scaling | \(\hat z = (\hat c/c)\,z\) | 1 % → 0.3 mm at 30 mm |
| Slowness linearization | \(\Delta c \approx -c_0^{2}\Delta s\) | 1 ns/mm = 2.37 m/s; error \(\Delta c^{2}/c\) |
| Coherence factor | \(\lvert\sum s_i\rvert^{2}/(N\sum\lvert s_i\rvert^{2})\) | CF = 0.5 at an edge phase of 2.73 rad |
| Harmonic and RMS averages | \(V_h = \sum w_i c_i\), \(V_{\mathrm{rms}}^{2} = \sum w_i c_i^{2}\) | focus returns \(V_{\mathrm{rms}}\); difference ≈ Var/(2V) |
| Average to local (straight ray) | \(s(z) = d[z\bar s(z)]/dz\) | noise × \(\sqrt2\,z/\Delta z\): 85 m/s from 2 m/s at 30 mm, 1 mm |
| Dix interval speed | \(c_{\mathrm{int}}^{2} = \Delta(V_{\mathrm{rms}}^{2}T)/\Delta T\) | consistent inverse of focus-optimal speeds |
| CUTE datum | \(\Delta\tau = L_\theta - L_0\), \(L_\theta = \sec\theta\int \Delta s\,dz'\) | wrap at 1/(2f₀) = 100 ns at 5 MHz |
| Layer visibility | \((\sec\theta - 1)S\), CMA \(2(\sec\theta - 1)S\) | 3.5 % / 7.1 % of the layer delay at 15° |
| Phase jitter of a correlation | \(\sigma_\phi \approx \sqrt{1-\rho^{2}}/(\rho\sqrt{2N})\) | 0.93 ns at ρ 0.95, N 64, 5 MHz |
| Resolution matrix | \(\mathbf{R} = (\mathbf{A}^{T}\mathbf{A} + \lambda^{2}\mathbf{G}^{T}\mathbf{G})^{-1}\mathbf{A}^{T}\mathbf{A}\) | kernels elongated axially (missing cone) |
| Autofocus gradient | \(\partial\mathcal{L}/\partial\mathbf{s} = \mathbf{A}^{T}\nabla_\tau\mathcal{L}\) | differentiable beamforming = back-projection |
| Curvature CRLB | \(\sigma_c = 4c^{2}F^{2}\sigma_t\sqrt{45/(4N)}/z\) | 1.7 m/s: 64 el., 30 mm, 5 ns |
| Calibration bias | \(b \approx -c^{2}z\delta/X^{2}\) | −0.83 m/s per ns of edge error (64 el., 30 mm) |
| Liver numbers (Imbault 2017) | 1492–1604 m/s; cut-offs 1541 and 1555 m/s | the 14 m/s a liver estimator must resolve |
32.11Interview and qualifying-exam questions
I1Why does a 1540 m/s assumption hurt a high-frequency, low-F-number image more than a low-frequency, high-F-number one? · screen
The speed error appears as a curvature error, \(\delta\tau(X) = (\Delta c/c)X^{2}/(zc)\); in phase that is \(2\pi f_0\delta\tau\). Requiring less than π/4 at the edge gives \(\lvert\Delta c\rvert < c^{2}F^{2}/(2f_0z)\): inversely proportional to frequency and proportional to F². At 5 MHz and 30 mm: 7.9 m/s at F/1, 71 m/s at F/3. Follow-up: and the depth error? \((\Delta c/c)z\), independent of aperture: 0.3 mm per percent at 30 mm.
I2You sweep the assumed speed and maximize coherence in a liver ROI at 50 mm under 10 mm of subcutaneous fat. What number did you measure? · screen
An average of the path, specifically the RMS speed \(V_{\mathrm{rms}} = \sqrt{\sum w_i c_i^{2}}\) (time weights), because small-offset moveout under flat layers is hyperbolic with \(V_{\mathrm{rms}}\) (Dix). With 1450 over 1580 m/s it reads about 1553, 27 m/s below the liver, and only about 1 m/s above \(z/T\). Follow-up: how do you get the liver itself? Measure at several depths and invert (Dix or regularized), or use a local method (tomography, layer fit with the B-mode interfaces).
I3Derive the noise of a local speed obtained by differencing two average speeds. · onsite
\(z\bar s(z) = \int_0^{z}s\), so \(s_k = (z_k\bar s_k - z_{k-1}\bar s_{k-1})/\Delta z\). With independent errors \(\sigma_{\bar s} = \sigma_{\bar c}/c^{2}\) on each average, \(\sigma_{s} = \sigma_{\bar s}\sqrt{z_k^{2} + z_{k-1}^{2}}/\Delta z\), i.e. \(\sigma_{c,\mathrm{loc}} \approx \sqrt2(z/\Delta z)\sigma_{\bar c}\). 2 m/s averages 1 mm apart at 30 mm give 85 m/s. Follow-up: what fixes it? Larger Δz (resolution), Tikhonov with a discrepancy-chosen λ, or a layer prior from the image, each a different bias.
I4Explain CUTE to a beamforming engineer in two minutes, including what limits it. · onsite
Beamform the same region with \(c_0\) from several steered plane waves (and receive angles); for each pixel the echo phase changes between steering angles in proportion to the difference of the travel-time errors along the two paths, \(\Delta\tau = L_\theta - L_{\theta'}\), \(L_\theta = \sec\theta\int\Delta s\). Stack all pixels and angles into \(\mathbf{d} = \mathbf{A}\Delta\mathbf{s}\) and invert with regularization. Limits: phase wraps at \(1/(2f_0)\) (small steps, accumulate), speckle decorrelation between angles (common mid-angle pairing), limited angle (axial blur, layers and the mean nearly invisible), and the forward model (straight rays, echo-position shift). Follow-up: what did Stähli et al. change? Common mid-angle pairs and the echo-position term.
I5Why is a laterally uniform fat layer hard for echo-mode tomography? Quantify. · onsite
All steered paths cross it, with lengths \(d/\cos\theta\); the difference to 0° is \((\sec\theta - 1)S\), where \(S\) is the vertical delay. For 4 mm at 1450 m/s, \(S\) = 161 ns, but the 15° datum moves by 5.7 ns (11.4 ns for a symmetric common-mid-angle pair), comparable to a few times the 1 ns jitter of one datum. A constant offset of the mean behaves the same way. Follow-up: so how do you anchor the mean? A global coherence estimate, a calibrated a priori value, or physics beyond straight rays.
I6What is the phase jitter of a CUTE datum, and what is the cheapest way to halve it? · onsite
\(\sigma_\phi \approx \sqrt{1-\rho^{2}}/(\rho\sqrt{2N})\), the interferometric-phase CRLB; at ρ = 0.95, N = 64: 0.029 rad, 0.93 ns at 5 MHz. Halving it by kernel size needs 4N (resolution loss); raising ρ from 0.95 to 0.987 does the same. Hence pairing schemes that keep speckle correlated (common mid-angle, common midpoint), small angle steps and good SNR. Follow-up: when does the formula fail? Low ρ, small N: the distribution grows tails and wraps.
I7Your SoS tomography gives 25 m/s RMSE on a phantom. More angles or a better forward model? · research
Check which term dominates first. Rerun the inversion on data synthesized by your own forward model with your measured noise level: if that RMSE is small (a few m/s, as in m32_sos_tomography.m: 3.8 and 1.9 m/s), the 25 m/s is model error (straight rays, refraction, echo-position shift, discretization, lens) and more angles will not help. Then look at the resolution matrix to see whether the phantom features are resolvable at all. Follow-up: how would you validate the forward model alone? Full-wave simulation of the phantom geometry, compared datum by datum.
I8What is the relationship between differentiable-beamforming autofocus and CUTE? · research
With straight rays, each beamforming delay is \(\sum_j \ell_{ij}s_j\); the chain rule makes the gradient of any delay-based loss \(\mathbf{A}^{T}\nabla_\tau\mathcal{L}\), a back-projection along the same rays CUTE uses. Gradient descent is a nonlinear iterative tomography that recomputes the delays (and could recompute bent rays) at each step; the iteration count and TV play the role of λ. It shares CUTE's missing cone and benefits from the same correlated pairings (common midpoint). Follow-up: what does it buy? Losses evaluated on the actual beamformed data, any differentiable forward model, and easy priors.
I9Where do phase-based autofocus losses get stuck, and how would you initialize? · research
Wherever a residual delay difference exceeds half a period, the wrapped phase reverses and the loss has a secondary minimum: cycle skipping (Module 14). Long subaperture lags and high frequency make it worse. Initialize with a coherence- or CF-based global speed (smooth, wide basin), use lag-1 pairs with a correlation threshold (as in CMPE), and go from low to high frequency. Follow-up: can coherence alone be the loss? Yes, it is smooth but flat near the optimum and biased toward the path average.
I10Write the error budget for a liver sound-speed number reported to a hepatologist. · research
Random: curvature or phase CRLB divided by √M (sub-m/s after averaging). Biases: layer bias if an average is reported (17–45 m/s under 10 mm of fat at 30–80 mm), forward-model error (refraction, straight rays, echo position: tens of m/s in tomography), calibration (≈ 0.8 m/s per ns of edge delay error for 64 elements at 30 mm; lens speed and thickness), regularization and the a priori mean. Compare with 14 m/s between the Imbault cut-offs. Follow-up: how do you validate? Phantoms with through-transmission references (±5 m/s), then patients against MRI-PDFF.
I11Would you trust a deep network that outputs a sound-speed map from channel data? · research
Only inside its training distribution. Feigin et al. (2020) trained on 6,026 k-Wave simulations of random ellipses and reported 20.5 m/s RMSE on simulated test data, with qualitative results in vivo: the forward model is now the simulator, and anatomy, lens, attenuation and noise mismatches become an unseen domain gap. I would want physics anchoring (unrolled or model-based inversion), uncertainty estimates and benchmark results on independent data such as QUASOS. Follow-up: what is a good sanity test? Feed a homogeneous phantom with known speed and a layered phantom; check the mean and the layer bias.
32.12MATLAB lab
Base MATLAB only (no toolboxes); each script runs as-is in MATLAB R2019b+ and GNU Octave 8. Paste into the editor and press Run. The numbers below are the Octave output.
m32_global_sos_focus.mSnell-traced channel data under a fat layer, CF versus assumed speed at 9 depths, Vh versus Vrms, Dix and straight-ray interval speeds · change c_fat, d_fat, c_liv, Nel · runtime ≈ 2 s
%% m32_global_sos_focus.m
% Global sound speed by focus-quality maximization in a two-layer medium.
% Purpose : Simulate channel data (0 deg plane-wave transmit, 64-element
% receive, 5 MHz) from wire targets under a 10 mm fat layer
% (1450 m/s) over liver (1580 m/s). Receive times are ray-traced
% with Snell's law (refraction included). For each target, sweep
% the assumed speed c_hat, beamform a small ROI tied to two-way
% time, and keep the c_hat that maximizes the coherence factor.
% Compare with two averages of the true profile:
% harmonic (time-average) V_h = z / T, T = sum d_i/c_i
% RMS (Dix) V_rms = sqrt( sum c_i^2 dT_i / T )
% Then invert the measured averages to interval (local) speeds
% with the straight-ray rule (dz/dT) and with Dix (d(V^2 T)/dT).
% Change : c_fat, d_fat, c_liv, f0, the receive aperture Nel.
% Expect : best c_hat follows V_rms within about 1 m/s (0.6-1.0 m/s
% high) and sits 1.5-2.3 m/s above V_h; V_rms exceeds V_h by
% w1 w2 (c2 - c1)^2 / (2 V_h), about 1.1 m/s at 40 mm; the interval
% speed below the fat is recovered to < 1 m/s by Dix and to
% 0.5-2.5 m/s by the straight-ray rule; the shallow fat target
% gives 1450.
% Runtime : about 3 s in Octave.
clear; close all; rng(1);
c_fat = 1450; d_fat = 10e-3; c_liv = 1580; % layer speeds (m/s), fat thickness (m)
f0 = 5e6; fs = 40e6; sig_t = 0.12e-6; % centre frequency, sampling, Gaussian envelope std (s)
Nel = 64; pitch = 0.3e-3; % receive elements, pitch (m)
xe = ((0:Nel-1) - (Nel-1)/2)*pitch; % element positions (m)
zt = [6 15 20 25 30 35 40 45 50]*1e-3; % wire depths on axis (m)
nT = numel(zt);
% ---- ray tracing: one-way time from element (xe,0) to wire (0,z), Snell refraction
Trec = zeros(nT, Nel); Ttx = zeros(nT, 1);
for k = 1:nT
z = zt(k);
if z <= d_fat
Trec(k, :) = sqrt(z^2 + xe.^2)/c_fat; Ttx(k) = z/c_fat; continue;
end
d2 = z - d_fat; X = abs(xe);
lo = zeros(size(X)); hi = (1/c_liv)*(1 - 1e-12)*ones(size(X)); % ray parameter p (s/m)
for it = 1:60
p = (lo + hi)/2;
f = d_fat*p*c_fat./sqrt(1 - (p*c_fat).^2) + d2*p*c_liv./sqrt(1 - (p*c_liv).^2);
hi(f > X) = p(f > X); lo(f <= X) = p(f <= X);
end
p = (lo + hi)/2;
Trec(k, :) = d_fat./(c_fat*sqrt(1 - (p*c_fat).^2)) + d2./(c_liv*sqrt(1 - (p*c_liv).^2));
Ttx(k) = d_fat/c_fat + d2/c_liv; % 0 deg plane wave: vertical path through flat layers
end
% ---- channel data as baseband IQ (analytic RF times exp(-j w0 t))
t = (0:round(80e-6*fs))/fs; % fast time (s)
IQ = zeros(numel(t), Nel);
for k = 1:nT
tau = Ttx(k) + Trec(k, :); % two-way arrival per element (s)
D = bsxfun(@minus, t(:), tau); % time relative to arrival
IQ = IQ + exp(-D.^2/(2*sig_t^2)).*exp(-1j*2*pi*f0*repmat(tau, numel(t), 1));
end
IQ = IQ + 0.01*(randn(size(IQ)) + 1j*randn(size(IQ)))/sqrt(2); % -40 dB noise
% ---- sweep c_hat, coherence factor over a time-tied ROI around each wire
chat = 1400:1:1650;
CF = zeros(nT, numel(chat));
Nt = numel(t);
xr = (-0.1:0.05:0.1)*1e-3; % ROI lateral positions (m), inside the PSF main lobe
for k = 1:nT
t0 = Ttx(k) + min(Trec(k, :)); % two-way apex time of the wire (s)
tr = t0 + (-0.05:0.01:0.05)*1e-6; % ROI in two-way time (s), +-39 um
[TR, XR] = ndgrid(tr, xr); TR = TR(:); XR = XR(:); % pixels, column vectors
for q = 1:numel(chat)
ch = chat(q); zh = ch*TR/2; % pixel depth tied to time
tau = zh/ch + sqrt(zh.^2 + bsxfun(@minus, XR, xe).^2)/ch; % 0 deg tx + rx delay, Npix x Nel
u = tau*fs + 1; i0 = floor(u); fr = u - i0; i0 = min(max(i0, 1), Nt - 1);
lin = bsxfun(@plus, i0, (0:Nel-1)*Nt); % linear indices into IQ
s = (1 - fr).*IQ(lin) + fr.*IQ(lin + 1); % linear interpolation of baseband IQ
s = s.*exp(1j*2*pi*f0*tau); % remodulate to the focused phase
CF(k, q) = sum(abs(sum(s, 2)).^2)/(Nel*sum(abs(s(:)).^2)); % energy-weighted CF over the ROI
end
end
% ---- results versus the two averages
Vh = zeros(nT, 1); Vr = zeros(nT, 1); best = zeros(nT, 1); T1 = zeros(nT, 1);
fprintf(' z (mm) best c_hat V_h (harm.) V_rms (Dix) best - V_h best - V_rms CF max\n');
for k = 1:nT
z = zt(k); d1 = min(z, d_fat); d2 = max(0, z - d_fat);
dT = [d1/c_fat, d2/c_liv]; T1(k) = sum(dT);
Vh(k) = z/T1(k); Vr(k) = sqrt((c_fat^2*dT(1) + c_liv^2*dT(2))/T1(k));
[m, i] = max(CF(k, :)); i = min(max(i, 2), numel(chat) - 1);
y = CF(k, i-1:i+1); best(k) = chat(i) + 0.5*(y(1) - y(3))/(y(1) - 2*y(2) + y(3)); % parabolic refinement
fprintf(' %5.0f %9.1f %10.1f %10.1f %9.1f %11.1f %6.3f\n', z*1e3, best(k), Vh(k), Vr(k), best(k) - Vh(k), best(k) - Vr(k), m);
end
% ---- interval speeds from the measured averages (one-way times T1 known from the echo times)
fprintf('\nInterval speed between successive wires (true liver %d m/s):\n', c_liv);
fprintf(' interval (mm) straight-ray dz/dT Dix sqrt(d(V^2 T)/dT)\n');
for k = 3:nT
zs_k = best(k)*T1(k); zs_j = best(k-1)*T1(k-1);
c_str = (zs_k - zs_j)/(T1(k) - T1(k-1));
c_dix = sqrt((best(k)^2*T1(k) - best(k-1)^2*T1(k-1))/(T1(k) - T1(k-1)));
fprintf(' %4.0f-%-4.0f %10.1f %10.1f\n', zt(k-1)*1e3, zt(k)*1e3, c_str, c_dix);
end
k40 = find(zt == 40e-3); w1 = (d_fat/c_fat)/T1(k40); w2 = 1 - w1;
fprintf('Prediction V_rms - V_h ~ w1 w2 (c_liv - c_fat)^2/(2 V_h) at 40 mm: %.2f m/s (exact %.2f)\n', ...
w1*w2*(c_liv - c_fat)^2/(2*Vh(k40)), Vr(k40) - Vh(k40));
figure('Position', [50 50 1000 420]);
subplot(1, 2, 1);
plot(chat, CF(zt == 15e-3, :)/max(CF(zt == 15e-3, :)), 'b', chat, CF(zt == 30e-3, :)/max(CF(zt == 30e-3, :)), 'r', ...
chat, CF(zt == 50e-3, :)/max(CF(zt == 50e-3, :)), 'k', 'LineWidth', 1.4);
xlabel('assumed sound speed c_{hat} (m/s)'); ylabel('CF / max'); legend('z = 15 mm', 'z = 30 mm', 'z = 50 mm', 'Location', 'southwest');
title('Coherence factor versus assumed speed'); grid on;
subplot(1, 2, 2);
plot(best, zt*1e3, 'ko', Vh, zt*1e3, 'b-', Vr, zt*1e3, 'r--', 'LineWidth', 1.4); set(gca, 'YDir', 'reverse');
xlabel('speed (m/s)'); ylabel('depth (mm)'); legend('CF-optimal c_{hat}', 'V_h = z/T', 'V_{rms} (Dix)', 'Location', 'southwest');
title('The focus-optimal speed is an average'); grid on;
What to look for: the CF-optimal speed is 1450.4 m/s at 6 mm (inside the fat), then 1493.1, 1514.5, … 1553.7 m/s from 15 to 50 mm, always 0.6–1.0 m/s above \(V_{\mathrm{rms}}\) and 1.5–2.3 m/s above \(V_h\); at 40 mm \(V_{\mathrm{rms}} - V_h\) = 1.07 m/s, exactly the prediction of (32.4). Interval speeds of the liver (true 1580): 1580.1–1580.6 m/s by Dix, 1580.5–1582.5 m/s by straight-ray differences.
m32_layered_inversion.mNoisy averages to local speeds: naive differencing (with Monte Carlo of its noise), Tikhonov with the discrepancy principle, layer-constrained least squares · change sig_c, dz, the profile · runtime ≈ 1 s
%% m32_layered_inversion.m
% From average to local sound speed in a layered medium (straight-ray model).
% Purpose : A global estimator (Section 32.2) returns the average speed down
% to each depth, c_avg(z) = z / T(z), T(z) = int_0^z s(z') dz'.
% In slowness this is linear: z * s_avg(z) = int_0^z s dz', so the
% local slowness is the derivative of z * s_avg. Differencing two
% noisy averages amplifies their noise by about sqrt(2) z / dz.
% Compare three inversions of the same noisy c_avg(z):
% (1) naive differencing on the measurement grid,
% (2) Tikhonov with a first-difference penalty, lambda chosen by
% the discrepancy principle (residual = expected noise),
% (3) layer-constrained least squares (interfaces known from the
% B-mode image, one unknown speed per layer).
% Change : sig_c (m/s noise on each average), dz (depth step), the profile.
% Expect : naive local error ~ 1.41 z/dz * sig_c (about 85 m/s at 30 mm for
% sig_c = 2 m/s, dz = 1 mm); Tikhonov recovers the liver to a few
% m/s but rounds the interfaces; the layer fit gives each layer to
% +-1 to 3 m/s, worst for the thin muscle layer. Monte Carlo exceeds
% the linear noise rule where errors reach ~10 % (1/s is nonlinear).
% Runtime : about 1 s in Octave.
clear; close all; rng(1);
dz = 1e-3; zg = (dz:dz:60e-3)'; % cell bottoms (m), 60 cells of 1 mm
n = numel(zg); zc = zg - dz/2; % cell centres
iface = [8e-3 14e-3]; % fat | muscle | liver interfaces (m)
cl = [1450 1585 1550]; % fat, muscle, liver speeds (m/s)
lay = 1 + (zc > iface(1)) + (zc > iface(2)); % layer index of every cell
c_true = cl(lay)'; s_true = 1./c_true; % local speed and slowness
km = (4:60)'; zk = zg(km); m = numel(km); % averages measured at 4..60 mm
A = double(bsxfun(@le, (1:n), km))*dz; % b_k = z_k * s_avg(z_k) = sum_{j<=k} s_j dz
cavg_true = zk./(A*s_true);
sig_c = 2; % noise on each c_avg (m/s)
cavg = cavg_true + sig_c*randn(m, 1);
b = zk./cavg; % measured z * s_avg (s)
% (1) naive differencing
s_naive = diff(b)/dz; z_naive = zk(2:end) - dz/2; c_naive = 1./s_naive;
% predicted noise amplification of (1): sigma_s,k = sigma_savg sqrt(z_k^2 + z_{k-1}^2)/dz
sig_savg = sig_c./cavg_true.^2;
pred = sqrt(zk(2:end).^2 + zk(1:end-1).^2)/dz .* sig_savg(2:end) .* c_true(km(2:end)).^2; % in m/s
% Monte Carlo check of (1)
R = 400; E = zeros(R, m-1);
for r = 1:R
bb = zk./(cavg_true + sig_c*randn(m, 1));
E(r, :) = (1./(diff(bb)/dz))' - c_true(km(2:end))';
end
mc = std(E)';
k30 = find(abs(z_naive - 29.5e-3) < 1e-6); k50 = find(abs(z_naive - 49.5e-3) < 1e-6);
fprintf('Naive differencing, std of local c: predicted %.1f / MC %.1f m/s at 30 mm; %.1f / %.1f at 50 mm (rule 1.41 z/dz sig_c: %.0f, %.0f)\n', ...
pred(k30), mc(k30), pred(k50), mc(k50), sqrt(2)*30*sig_c, sqrt(2)*50*sig_c);
% (2) Tikhonov with first-difference penalty, discrepancy principle
D = diff(eye(n));
W = diag(1./(zk.*sig_savg)); % whiten: std of b_k = z_k * sigma_savg
lams = logspace(1, 9, 120); res = zeros(size(lams));
for q = 1:numel(lams)
s_q = (A'*W'*W*A + lams(q)^2*(D'*D)) \ (A'*W'*W*b);
res(q) = norm(W*(A*s_q - b))^2;
end
qd = find(res <= m, 1, 'last'); lam = lams(qd); % largest lambda with chi^2 <= number of data
s_tik = (A'*W'*W*A + lam^2*(D'*D)) \ (A'*W'*W*b); c_tik = 1./s_tik;
liv = zc > 20e-3;
fprintf('Tikhonov (discrepancy, lambda = %.2g): liver (20-60 mm) mean %.1f m/s, RMSE %.1f m/s; whole-profile RMSE %.1f m/s\n', ...
lam, mean(c_tik(liv)), sqrt(mean((c_tik(liv) - c_true(liv)).^2)), sqrt(mean((c_tik - c_true).^2)));
% (3) layer-constrained least squares: s = P * s_layer, P(j,l) = 1 if cell j is in layer l
P = double(bsxfun(@eq, lay, 1:3));
B = W*A*P; s_lay = B \ (W*b); C = inv(B'*B); % covariance of the layer slownesses
c_lay = 1./s_lay; sd_lay = sqrt(diag(C)).*c_lay.^2;
fprintf('Layer fit: fat %.1f +- %.1f, muscle %.1f +- %.1f, liver %.1f +- %.1f m/s (true %d, %d, %d)\n', ...
c_lay(1), sd_lay(1), c_lay(2), sd_lay(2), c_lay(3), sd_lay(3), cl);
fprintf('Average at 60 mm: %.1f m/s, i.e. %.1f m/s below the liver value it is often mistaken for\n', ...
cavg_true(end), cl(3) - cavg_true(end));
figure('Position', [40 40 1050 430]);
subplot(1, 2, 1);
plot(c_true, zc*1e3, 'k-', 'LineWidth', 2); hold on;
plot(cavg, zk*1e3, 'b.', 'MarkerSize', 10);
plot(c_naive, z_naive*1e3, 'Color', [0.8 0.5 0.5]);
plot(c_tik, zc*1e3, 'r-', 'LineWidth', 1.6);
stairs([c_lay(lay)' c_lay(3)], [0; zg]*1e3, 'g--', 'LineWidth', 1.4);
set(gca, 'YDir', 'reverse'); xlim([1300 1800]); ylim([0 60]); grid on;
xlabel('sound speed (m/s)'); ylabel('depth (mm)');
legend('true local', 'measured average', 'naive difference', 'Tikhonov', 'layer fit', 'Location', 'northeast');
title(sprintf('Average-to-local inversion, sigma_c = %g m/s', sig_c));
subplot(1, 2, 2);
plot(z_naive*1e3, mc, 'k.', z_naive*1e3, pred, 'r-', 'LineWidth', 1.4); grid on;
xlabel('depth (mm)'); ylabel('std of local c (m/s)'); legend('Monte Carlo', 'sqrt(z_k^2 + z_{k-1}^2)/dz rule', 'Location', 'northwest');
title('Noise amplification of naive differencing');
What to look for: naive local noise 85.8 m/s predicted and 87.1 m/s by Monte Carlo at 30 mm (142.4 and 147.6 at 50 mm) from 2 m/s per average; Tikhonov at λ = 1.5×10⁵ gives the liver at 1548.6 m/s (RMSE 6.8 m/s, 10.5 m/s over the whole profile); the layer fit gives 1449.3 ± 0.8, 1587.6 ± 2.5 and 1548.9 ± 0.7 m/s (true 1450, 1585, 1550); the average at 60 mm is 1539.2 m/s.
m32_cute_phase_shift.mStraight-ray CUTE delay maps (transmit-only, common mid-angle, 2° step) for an inclusion under fat, and a Monte Carlo of the phase jitter of correlated speckle · change th_deg, dc_inc, rho_list, N_list · runtime ≈ 3 s
%% m32_cute_phase_shift.m
% CUTE-style echo phase shifts between steered acquisitions (ray model) and
% the phase jitter that limits them (speckle Monte Carlo).
% Purpose : (A) Straight-ray, first-order model of the beamforming delay
% error of every pixel r for a steering angle th:
% L_th(r) = sec(th) * int_0^z ds(x - (z - z') tan th, z') dz',
% ds = 1/c - 1/c0 (c0 = 1540 m/s assumed by the beamformer).
% Two data types are mapped for a +40 m/s inclusion under a fat layer:
% transmit-only pair d = L_th - L_0 (receive fixed)
% common mid-angle d = L_th + L_-th - 2 L_0 (tx th, rx -th)
% Echo-position shifts and refraction are neglected.
% (B) The phase of the complex correlation of two speckle kernels of
% N independent samples and correlation rho has std
% sigma_phi ~ sqrt(1 - rho^2) / (rho sqrt(2N)) (large N),
% checked by Monte Carlo; sigma_tau = sigma_phi / (2 pi f0).
% Change : th_deg, dc_inc, r_inc, the fat layer, rho_list, N_list.
% Expect : at 15 deg the shift below the inclusion centre (0 deg path through
% the full chord, 15 deg path missing it) reaches the chord delay
% (164 ns) plus 5.7 ns from the fat layer, ~169 ns, several phase wraps at 5 MHz; a 2 deg step
% stays below 100 ns (no wrap), zero above the inclusion; the layer adds only (sec th - 1) of its
% vertical delay; the jitter formula holds within ~10 % for N = 64
% and fails at low rho and small N (phase wrapping, bias).
% Runtime : about 2 s in Octave.
clear; close all; rng(1);
c0 = 1540; f0 = 5e6;
dx = 0.1; x = -19.2:dx:19.2; z = 0:dx:40; % grid (mm)
[X, Z] = meshgrid(x, z);
dc_inc = 40; r_inc = 5; zi = 15; % inclusion: +40 m/s, radius 5 mm, centre depth 15 mm
c = c0 + dc_inc./(1 + exp((hypot(X, Z - zi) - r_inc)/0.3)); % smooth edge, 0.3 mm
d_fat = 4; c(Z < d_fat) = 1450; % 4 mm fat layer at the top
ds = (1./c - 1/c0)*1e6; % slowness deviation (ns/mm)
th_deg = 15; ths = [-th_deg 0 th_deg 2]*pi/180; L = cell(1, 4);
for a = 1:4
th = ths(a); La = zeros(size(ds));
La(1, :) = ds(1, :)*dx/cos(th)/2; % half cell at the surface
for k = 2:numel(z) % march down: shift the previous row by dz tan(th)
prev = interp1(x, La(k-1, :), x - dx*tan(th), 'linear', 'extrap');
La(k, :) = prev + 0.5*(ds(k, :) + ds(k-1, :))*dx/cos(th);
end
L{a} = La; % ns, delay error of each pixel for angle th
end
d_tx = L{3} - L{2}; % transmit-only pair (th vs 0)
d_cma = L{3} + L{1} - 2*L{2}; % common mid-angle pair (th,-th) vs (0,0)
in_ap = abs(X) < 12; % keep away from the lateral edges
fprintf('Inclusion %+d m/s: ds = %.2f ns/mm, vertical delay through its centre %.1f ns\n', dc_inc, ...
(1/(c0 + dc_inc) - 1/c0)*1e6, (1/(c0 + dc_inc) - 1/c0)*1e6*2*r_inc);
fprintf('Peak |d| at th = %d deg: transmit-only %.1f ns (%.2f rad at %.0f MHz), common mid-angle %.1f ns (%.2f rad)\n', th_deg, ...
max(abs(d_tx(in_ap))), 2*pi*f0*max(abs(d_tx(in_ap)))*1e-9, f0/1e6, max(abs(d_cma(in_ap))), 2*pi*f0*max(abs(d_cma(in_ap)))*1e-9);
d2 = L{4} - L{2};
fprintf('Adjacent-angle step of 2 deg (tx-only): peak |d| %.1f ns (%.2f rad): no wrapping; wrapping starts at |d| = 1/(2 f0) = %.0f ns\n', ...
max(abs(d2(in_ap))), 2*pi*f0*max(abs(d2(in_ap)))*1e-9, 1e9/(2*f0));
k30 = find(abs(z - 30) < 1e-9); i0 = find(abs(x + 15) < 1e-9); % a column far from the inclusion
S = (1/1450 - 1/c0)*1e6*d_fat;
fprintf('Fat layer only (x = -15 mm, z = 30 mm): vertical %.1f ns, tx-only %.2f ns (pred (sec-1)S = %.2f), CMA %.2f ns (pred 2(sec-1)S = %.2f)\n', ...
L{2}(k30, i0), d_tx(k30, i0), (sec(ths(3)) - 1)*S, d_cma(k30, i0), 2*(sec(ths(3)) - 1)*S);
% (B) phase jitter of the complex correlation of two speckle kernels
rho_list = [0.5 0.7 0.9 0.95 0.99]; N_list = [16 64]; R = 4000;
fprintf('\n rho N sigma_phi MC (rad) formula sigma_tau at 5 MHz (ns)\n');
SPH = zeros(numel(N_list), numel(rho_list));
for iN = 1:numel(N_list)
N = N_list(iN);
for ir = 1:numel(rho_list)
rho = rho_list(ir); phi0 = 0.4;
a1 = (randn(N, R) + 1j*randn(N, R))/sqrt(2);
w = (randn(N, R) + 1j*randn(N, R))/sqrt(2);
a2 = (rho*a1 + sqrt(1 - rho^2)*w)*exp(1j*phi0);
ph = angle(sum(a2.*conj(a1), 1)) - phi0;
SPH(iN, ir) = std(ph);
fo = sqrt(1 - rho^2)/(rho*sqrt(2*N));
fprintf(' %.2f %3d %10.4f %8.4f %8.2f\n', rho, N, SPH(iN, ir), fo, SPH(iN, ir)/(2*pi*f0)*1e9);
end
end
th = 20*pi/180; dzl = 5; sig_tau = sqrt(1 - 0.95^2)/(0.95*sqrt(128))/(2*pi*f0)*1e9;
% layer delay S = datum below minus datum above the layer: two independent data, sqrt(2) sigma_tau
sig_s = sqrt(2)*sig_tau/(2*(sec(th) - 1)*dzl);
fprintf('\nLayer slowness from CMA data below minus above a %d mm layer at +-20 deg, sigma_tau = %.2f ns per datum (rho 0.95, N 64): sigma_s = %.1f ns/mm = %.0f m/s\n', ...
dzl, sig_tau, sig_s, sig_s*1e-6*c0^2);
figure('Position', [40 40 1150 380]); colormap(jet);
subplot(1, 3, 1); imagesc(x, z, c); axis image; colorbar; title('true c (m/s)'); xlabel('x (mm)'); ylabel('z (mm)');
subplot(1, 3, 2); imagesc(x, z, d_tx); axis image; colorbar; caxis([-180 180]);
title(sprintf('tx-only: L_{%d} - L_0 (ns)', th_deg)); xlabel('x (mm)');
subplot(1, 3, 3); imagesc(x, z, d_cma); axis image; colorbar; caxis([-180 180]);
title(sprintf('CMA: L_{%d} + L_{-%d} - 2L_0 (ns)', th_deg, th_deg)); xlabel('x (mm)');
figure('Position', [60 60 560 380]);
semilogy(rho_list, SPH(1, :), 'bo', rho_list, SPH(2, :), 'ro', 'LineWidth', 1.4); hold on;
rr = linspace(0.45, 0.995, 200);
semilogy(rr, sqrt(1 - rr.^2)./(rr*sqrt(2*16)), 'b-', rr, sqrt(1 - rr.^2)./(rr*sqrt(2*64)), 'r-');
grid on; xlabel('correlation coefficient rho'); ylabel('phase std (rad)');
legend('MC N = 16', 'MC N = 64', 'formula N = 16', 'formula N = 64', 'Location', 'southwest');
title('Phase jitter of the complex correlation');
What to look for: inclusion slowness −16.44 ns/mm; peak shift at 15° of 168.9 ns (5.31 rad) transmit-only and 335.4 ns (10.54 rad) common mid-angle; 56.2 ns for a 2° step (no wrap below 100 ns); the fat layer alone gives 5.69 and 11.37 ns, matching \((\sec\theta - 1)S\) and \(2(\sec\theta - 1)S\). Phase jitter: 0.0295 rad by Monte Carlo against 0.0291 from (32.10) at ρ = 0.95, N = 64; at ρ = 0.5, N = 16 the formula underestimates (0.306 versus 0.355 rad). A 5 mm layer from CMA data at ±20° with 0.92 ns jitter on the data above and below it (√2 × 0.92 ns on their difference): σs = 2.0 ns/mm = 5 m/s.
m32_sos_tomography.mLimited-angle echo-mode tomography with transmit-only and CMA data, Tikhonov with gradient penalty, resolution-matrix kernels, singular spectra, and an error budget that separates noise from model error · change thmax, K, noise_ns, the truth · runtime ≈ 6 s
%% m32_sos_tomography.m
% Limited-angle echo-mode SoS tomography: two acquisition designs, the
% resolution matrix versus depth, and the singular spectrum.
% Purpose : Unknown: slowness deviation ds = 1/c - 1/c0 on 16 x 14 cells of
% 2.4 mm (x = +-19.2 mm, z = 2 to 35.6 mm) under a 38.4 mm array.
% Data at every cell centre, built from straight-ray delay errors
% L_phi(r) (line integral of ds from r to the array at angle phi):
% 'tx-only' transmit steered, receive fixed at 0 deg; adjacent
% transmit angles differenced: d = L_phi(k) - L_phi(k-1)
% 'CMA' transmit phi_i and receive phi_j from the same angle set;
% pairs grouped by mid-angle (phi_i + phi_j)/2 and
% adjacent pairs in a group differenced
% Tikhonov with a gradient penalty; oracle lambda (minimum RMSE
% against the truth), the best case for each design. R = (A'A + lam^2 G'G)^-1 A'A: row k is the point-spread
% function of the reconstruction at cell k.
% Data come from 0.05 mm ray steps through a smooth truth; the
% inversion uses 0.3 mm steps with nearest-cell weights.
% Change : thmax, K, noise_ns, the truth.
% Expect : CMA gives about 2.2x more rows, yet in this straight-ray model
% every CMA row (W_i + W_j) - (W_i-1 + W_j+1) is a combination of
% the tx-only rows of the same pixel (printed residual ~1e-15): CMA
% adds no ray information. Its real-data advantage (higher speckle
% correlation, no echo-position bias) is outside this model.
% The error budget is printed per design: with data consistent with
% the cell model the error comes from noise + regularization; with
% fine-ray data it is dominated by model (discretization) error,
% which is larger than the 2 ns noise effect. Both designs smear
% axially more than laterally and worse with depth; the 5 mm fat
% layer comes back near 1506 m/s instead of 1450.
% Runtime : about 6 s in Octave.
clear; close all; rng(2);
c0 = 1540; Nx = 16; Nz = 14; h = 2.4; % reference speed, grid, cell size (mm)
xc = ((0:Nx-1) - (Nx-1)/2)*h; zc = 2 + ((0:Nz-1) + 0.5)*h;
np = Nx*Nz; Xh = 19.2; % unknowns, array half-width (mm)
sg = @(r, r0) 1./(1 + exp((r - r0)/0.4));
truth = @(x, z) 1540 + 40*sg(hypot(x - 2, z - 20), 4.5) - 90*(z < 5); % inclusion + 5 mm fat (1450)
dsf = @(c) (1./c - 1/c0)*1e6; % ns/mm
[XX, ZZ] = meshgrid(xc, zc); ct = reshape(truth(XX, ZZ)', [], 1); % index = iz*Nx + ix + 1
cellof = @(x, z) min(max(floor((z - 2)/h), 0), Nz-1)*Nx + min(max(floor((x + Xh)/h), 0), Nx-1) + 1;
% straight-ray integral from point (x0,z0) to the surface at angle phi
% (weights over cells for the inversion; fine numerical value for the data)
ray_w = @(x0, z0, phi, st) accumarray(cellof(x0 - (0:st:z0/cos(phi))'*sin(phi), z0 - (0:st:z0/cos(phi))'*cos(phi)), st, [np 1])';
ray_d = @(x0, z0, phi) sum(dsf(truth(x0 - (0:0.05:z0/cos(phi))*sin(phi), z0 - (0:0.05:z0/cos(phi))*cos(phi))))*0.05;
% gradient penalty
I = speye(np); G = [];
for iz = 0:Nz-1, for ix = 0:Nx-2, k = iz*Nx + ix + 1; G = [G; I(k+1, :) - I(k, :)]; end, end %#ok<AGROW>
for iz = 0:Nz-2, for ix = 0:Nx-1, k = iz*Nx + ix + 1; G = [G; I(k+Nx, :) - I(k, :)]; end, end %#ok<AGROW>
GG = full(G'*G);
thmax = 25; K = 7; noise_ns = 2; phis = linspace(-thmax, thmax, K)*pi/180;
designs = {'tx-only', 'CMA'}; fw = @(p, dd) dd*0.01*sum(interp1(1:numel(p), p, 1:0.01:numel(p)) >= max(p)/2);
fprintf('theta_max = %d deg, K = %d angles, delay noise %.1f ns\n', thmax, K, noise_ns);
fprintf(' design rows lambda trace(R) RMSE (m/s) incl. mean (true %.0f) fat mean (true 1450) axial / lateral FWHM (mm) at z = 9, 19, 31 mm\n', truth(2, 20));
res = struct(); rowres = 0;
for dsg = 1:2
Arows = []; d = [];
for iz = 1:Nz
for ix = 1:Nx
x0 = xc(ix); z0 = zc(iz);
ok = abs(x0 - z0*tan(phis)) <= Xh; % ray must reach the aperture
Wp = zeros(K, np); Dp = zeros(K, 1);
for a = 1:K
if ok(a), Wp(a, :) = ray_w(x0, z0, phis(a), 0.3); Dp(a) = ray_d(x0, z0, phis(a)); end
end
if dsg == 1 % tx-only: receive fixed at 0 deg (cancels)
for a = 2:K
if ok(a) && ok(a-1), Arows = [Arows; Wp(a, :) - Wp(a-1, :)]; d = [d; Dp(a) - Dp(a-1)]; end %#ok<AGROW>
end
else % CMA: tx i, rx j, group by mid-angle
Tp = []; for a = 2:K, if ok(a) && ok(a-1), Tp = [Tp; Wp(a, :) - Wp(a-1, :)]; end, end %#ok<AGROW>
Cp = [];
for gsum = 2:2*K
pr = [];
for i = max(1, gsum-K):min(K, gsum-1), j = gsum - i; if i <= j && ok(i) && ok(j), pr = [pr; i j]; end, end %#ok<AGROW>
for q = 2:size(pr, 1)
w1 = Wp(pr(q, 1), :) + Wp(pr(q, 2), :); w0 = Wp(pr(q-1, 1), :) + Wp(pr(q-1, 2), :);
Arows = [Arows; w1 - w0]; d = [d; Dp(pr(q, 1)) + Dp(pr(q, 2)) - Dp(pr(q-1, 1)) - Dp(pr(q-1, 2))]; %#ok<AGROW>
Cp = [Cp; w1 - w0]; %#ok<AGROW>
end
end
if ~isempty(Cp) && ~isempty(Tp), rowres = max(rowres, norm(Cp - (Cp*pinv(Tp))*Tp, 'fro')/norm(Cp, 'fro')); end
end
end
end
m = size(Arows, 1); nse = noise_ns*randn(m, 1);
AA = Arows'*Arows; lams = logspace(-1, 4, 50);
orac = @(dd) min(arrayfun(@(L) sqrt(mean((1./(1/c0 + ((AA + L^2*GG) \ (Arows'*dd))*1e-6) - ct).^2)), lams));
rmse_cons = orac(Arows*dsf(ct) + nse); % data consistent with the cell model: noise + regularization only
rmse_nf = orac(d); % fine-ray data without noise: model error + regularization only
dn = d + nse; Ab = Arows'*dn; rr = zeros(size(lams));
for q = 1:numel(lams), sq = (AA + lams(q)^2*GG) \ Ab; rr(q) = sqrt(mean((1./(1/c0 + sq*1e-6) - ct).^2)); end
[~, qd] = min(rr); lam = lams(qd); % oracle lambda (minimum RMSE against the truth)
ds_hat = (AA + lam^2*GG) \ Ab; c_hat = 1./(1/c0 + ds_hat*1e-6);
Rm = (AA + lam^2*GG) \ AA;
inc = hypot(reshape(XX', [], 1) - 2, reshape(ZZ', [], 1) - 20) < 3;
fat = reshape(ZZ', [], 1) < 5;
ixc = find(abs(xc - 1.2) < 1e-9);
fwa = zeros(1, 3); fwl = zeros(1, 3); zq = [9 19 31];
for t = 1:3
iz = find(abs(zc - zq(t)) < 1.3, 1); k = (iz - 1)*Nx + ixc;
row = reshape(Rm(k, :), Nx, Nz)'; % Nz x Nx kernel
fwa(t) = fw(max(row(:, ixc), 0)', h); fwl(t) = fw(max(row(iz, :), 0), h);
end
fprintf(' %-8s %5d %6.2f %7.1f %7.1f %7.1f %7.1f %4.1f/%3.1f %4.1f/%3.1f %4.1f/%3.1f\n', designs{dsg}, m, lam, trace(Rm), ...
sqrt(mean((c_hat - ct).^2)), mean(c_hat(inc)), mean(c_hat(fat)), fwa(1), fwl(1), fwa(2), fwl(2), fwa(3), fwl(3));
fprintf(' RMSE with cell-consistent data + noise: %.1f m/s; fine-ray data without noise: %.1f m/s\n', rmse_cons, rmse_nf);
sv = svd(Arows); res(dsg).sv = sv/sv(1); res(dsg).c = c_hat; res(dsg).R = Rm;
end
fprintf('Singular values above 1e-2 of the largest: tx-only %d, CMA %d (of %d unknowns)\n', sum(res(1).sv > 1e-2), sum(res(2).sv > 1e-2), np);
fprintf('CMA rows of each pixel lie in the span of its tx-only rows: max relative residual %.1e\n', rowres);
figure('Position', [30 30 1150 640]); colormap(jet);
subplot(2, 3, 1); imagesc(xc, zc, reshape(ct, Nx, Nz)'); axis image; caxis([1440 1590]); colorbar; title('truth (m/s)'); ylabel('z (mm)');
subplot(2, 3, 2); imagesc(xc, zc, reshape(res(1).c, Nx, Nz)'); axis image; caxis([1440 1590]); colorbar; title('tx-only, Tikhonov');
subplot(2, 3, 3); imagesc(xc, zc, reshape(res(2).c, Nx, Nz)'); axis image; caxis([1440 1590]); colorbar; title('CMA, Tikhonov');
k = (find(abs(zc - 19) < 1.3, 1) - 1)*Nx + find(abs(xc - 1.2) < 1e-9);
subplot(2, 3, 4); semilogy(res(1).sv, 'b', 'LineWidth', 1.4); hold on; semilogy(res(2).sv, 'r', 'LineWidth', 1.4); grid on;
xlabel('index'); ylabel('\sigma_i / \sigma_1'); legend('tx-only', 'CMA', 'Location', 'southwest'); title('singular spectrum of A');
subplot(2, 3, 5); imagesc(xc, zc, reshape(res(1).R(k, :), Nx, Nz)'); axis image; colorbar; title('R row at (1.2, 19.4) mm, tx-only'); xlabel('x (mm)');
subplot(2, 3, 6); imagesc(xc, zc, reshape(res(2).R(k, :), Nx, Nz)'); axis image; colorbar; title('R row at (1.2, 19.4) mm, CMA'); xlabel('x (mm)');
What to look for: 1146 rows (transmit-only) and 2498 rows (CMA) for 224 unknowns; oracle-λ RMSE 22.2 and 30.6 m/s, inclusion mean 1558.6 and 1535.5 m/s (true 1580), fat row about 1506 m/s (true 1450) for both; axial/lateral FWHM 2.5/2.4, 2.6/2.4, 3.4/2.4 mm (transmit-only) and 2.6/2.4, 2.9/2.4, 4.2/2.4 mm (CMA) at 9, 19, 31 mm. The error budget: 3.8 and 1.9 m/s with cell-consistent data plus noise, 22.0 and 30.8 m/s with noise-free fine-ray data. Each pixel's CMA rows lie in the span of its transmit-only rows (residual 5.1×10⁻¹⁵). An earlier version of this script's header claimed CMA would give a larger trace(R) and a smaller axial kernel; the printed numbers show the opposite, and the header now explains why.
m32_sos_error_budget.mFisher information and CRLB of a wavefront-curvature speed estimate, checked by Monte Carlo; CRLB table versus depth and aperture; bias of a quadratic calibration error · change sigma_t, N, z_list · runtime ≈ 2 s
%% m32_sos_error_budget.m
% Error budget of a global sound-speed estimate from wavefront curvature:
% how per-element delay jitter becomes m/s (Fisher information / CRLB).
% Purpose : A point (or a coherent speckle patch) at depth z returns echoes
% whose receive arrival times across the aperture follow
% t_i = t_a + ( sqrt(z^2 + x_i^2) - z ) / c, z = c t_a,
% with t_a the apex (on-axis) one-way time, measured from the echo.
% Unknowns: c and an arrival offset t0 (common delay). The
% parabolic (small-aperture) limit gives a closed form
% sigma_c = c^2 z sigma_t sqrt(45/(4N)) / X^2
% = 4 c^2 F^2 sigma_t sqrt(45/(4N)) / z, F = z/(2X),
% for N elements uniformly spread over [-X, X] and independent
% per-element jitter sigma_t. (A) checks it against the exact
% Fisher matrix of the hyperbolic model and a Monte Carlo
% least-squares fit; (B) tabulates sigma_c against depth and
% aperture; (C) shows the bias from ignoring a 1 ns/element
% systematic delay error (e.g. lens or element delay calibration).
% Change : sigma_t, N, pitch, z_list, the systematic error pattern.
% Expect : closed form, exact CRLB and Monte Carlo agree within ~5 % (1.62,
% 1.69, 1.68 m/s for 64 elements, 5 ns jitter, z = 30 mm);
% sigma_c grows linearly with z at a fixed aperture and falls as
% N^-2.5 at fixed pitch (aperture^2 times sqrt(N)); a 1 ns
% quadratic calibration error at the aperture edge biases c by
% about -0.8 m/s (0.05 % of c per ns of the ~970 ns curvature),
% comparable to the CRLB and, unlike jitter, it never averages out.
% Runtime : about 2 s in Octave.
clear; close all; rng(3);
c = 1540; pitch = 0.3e-3; % true speed (m/s), pitch (m)
sigma_t = 5e-9; % per-element arrival-time jitter (s)
model = @(cc, t0, x, ta) t0 + ta + (sqrt((cc*ta)^2 + x.^2) - cc*ta)/cc; % one-way receive times (s)
% (A) one configuration: 64 elements, z = 30 mm
N = 64; x = ((0:N-1) - (N-1)/2)*pitch; X = max(abs(x)); z = 30e-3; ta = z/c;
h = 1e-3; % finite-difference step for the Jacobian (m/s and s)
J = [(model(c + h, 0, x, ta) - model(c - h, 0, x, ta))'/(2*h), ones(N, 1)]; % d t / d(c, t0)
F = (J'*J)/sigma_t^2; Ci = inv(F); crlb = sqrt(Ci(1, 1));
Xrms = sqrt(mean(x.^4) - mean(x.^2)^2); % discrete spread of x^2 (continuous: X^2 sqrt(4/45))
closed = c^2*z*sigma_t/(sqrt(N)*Xrms);
closed_u = c^2*z*sigma_t*sqrt(45/(4*N))/X^2;
R = 3000; est = zeros(R, 1);
for r = 1:R
tm = model(c, 0, x, ta) + sigma_t*randn(1, N);
p = [c; 0]; % Gauss-Newton on (c, t0)
for it = 1:6
res = tm' - model(p(1), p(2), x, ta)';
Jg = [(model(p(1) + h, p(2), x, ta) - model(p(1) - h, p(2), x, ta))'/(2*h), ones(N, 1)];
p = p + Jg \ res;
end
est(r) = p(1);
end
fprintf('(A) N = %d, aperture %.1f mm, z = %.0f mm (F = %.2f), sigma_t = %.0f ns\n', N, 2*X*1e3, z*1e3, z/(2*X), sigma_t*1e9);
fprintf(' exact CRLB %.2f m/s | parabolic closed form %.2f (uniform-aperture form %.2f) | Monte Carlo std %.2f, bias %+.2f m/s\n', ...
crlb, closed, closed_u, std(est), mean(est) - c);
% (B) table: sigma_c versus depth and aperture (exact CRLB)
z_list = [10 20 30 40 60 80]*1e-3; N_list = [32 64 128];
fprintf('\n(B) CRLB of c (m/s), sigma_t = %.0f ns\n z (mm) ', sigma_t*1e9); fprintf(' N = %3d (F) ', N_list); fprintf('\n');
S = zeros(numel(z_list), numel(N_list));
for iz = 1:numel(z_list)
fprintf(' %5.0f ', z_list(iz)*1e3);
for in = 1:numel(N_list)
Nn = N_list(in); xx = ((0:Nn-1) - (Nn-1)/2)*pitch; tz = z_list(iz)/c;
Jn = [(model(c + h, 0, xx, tz) - model(c - h, 0, xx, tz))'/(2*h), ones(Nn, 1)];
Ci = inv(Jn'*Jn)*sigma_t^2; S(iz, in) = sqrt(Ci(1, 1));
fprintf(' %7.2f (%4.2f)', S(iz, in), z_list(iz)/(2*max(abs(xx))));
end
fprintf('\n');
end
% (C) a systematic error: quadratic delay error of 1 ns at the aperture edge
e_sys = 1e-9*(x/X).^2; % s, e.g. lens/element delay calibration
p = [c; 0]; tm = model(c, 0, x, ta) + e_sys;
for it = 1:8
res = tm' - model(p(1), p(2), x, ta)';
Jg = [(model(p(1) + h, p(2), x, ta) - model(p(1) - h, p(2), x, ta))'/(2*h), ones(N, 1)];
p = p + Jg \ res;
end
fprintf('\n(C) 1 ns quadratic calibration error at the aperture edge: bias %+.2f m/s (CRLB at 5 ns jitter: %.2f m/s)\n', p(1) - c, crlb);
fprintf(' rule: the curvature of a 1540 m/s wavefront across this aperture is X^2/(2 z c) = %.0f ns; 1 ns of it is %.2f %% of c\n', ...
X^2/(2*z*c)*1e9, 100*1e-9/(X^2/(2*z*c))/2);
figure('Position', [60 60 980 380]);
subplot(1, 2, 1); hist(est, 40); xlabel('estimated c (m/s)'); ylabel('count');
title(sprintf('Monte Carlo, std %.2f m/s, CRLB %.2f m/s', std(est), crlb)); grid on;
subplot(1, 2, 2); loglog(z_list*1e3, S, 'o-', 'LineWidth', 1.4); grid on;
xlabel('depth z (mm)'); ylabel('CRLB of c (m/s)'); legend('N = 32', 'N = 64', 'N = 128', 'Location', 'northwest');
title(sprintf('Wavefront-curvature CRLB, sigma_t = %.0f ns', sigma_t*1e9));
What to look for: 64 elements, 30 mm, 5 ns: exact CRLB 1.69 m/s, closed form 1.62 m/s (1.67 continuous), Monte Carlo 1.68 m/s with +0.02 m/s bias. The table runs from 0.20 m/s (128 elements, 10 mm) to 24.5 m/s (32 elements, 80 mm), linear in depth and about \(N^{-2.5}\) in aperture. A 1 ns quadratic edge error biases the estimate by −0.83 m/s.
32.13Self-check
Q1At 7.5 MHz, F/1.5 and 25 mm, what speed error puts the edge phase at π/4?
\(\lvert\Delta c\rvert = c^{2}F^{2}/(2f_0z)\) = 2.37×10⁶ × 2.25 / (2 × 7.5×10⁶ × 0.025) = 14.2 m/s.
Q2A region at 1600 m/s is beamformed at 1540 m/s. Slowness deviation, and the linearized speed?
\(\Delta s\) = 1/1600 − 1/1540 = −24.35 ns/mm; \(-c_0^{2}\Delta s\) = 57.7 m/s against the true 60 m/s (error \(\Delta c^{2}/c\) ≈ 2.3 m/s).
Q315 mm of fat (1450 m/s) over liver (1560 m/s). Vh and Vrms at 60 mm?
\(\Delta T\) = 10.34 and 28.85 µs, T = 39.19 µs, \(w_1\) = 0.264. \(V_h\) = 60/39.19 = 1531.0 m/s; \(V_{\mathrm{rms}}\) = √(0.264 × 1450² + 0.736 × 1560²) = 1531.7 m/s. Both are about 29 m/s below the liver.
Q4Averages at 40 and 45 mm, each with 1 m/s noise. Noise on the local speed between them?
\(\sqrt{45^{2} + 40^{2}}/5\) × 1 = 12.0 m/s.
Q5A 3 mm-radius region at −30 m/s (relative to 1540). Maximum vertical chord delay, and does a 10° transmit-only step wrap at 6 MHz?
\(\Delta s\) = 1/1510 − 1/1540 = 12.9 ns/mm. The longest chord through a circle is its diameter in any direction, 6 mm, so no datum can exceed 77 ns, even if one path crosses the full chord and the other misses the region. Wrapping starts at 1/(2f₀) = 83 ns at 6 MHz: no wrap, whatever the step.
Q6CUTE kernel with N = 100 independent samples, ρ = 0.9, 5 MHz. Delay jitter?
\(\sigma_\phi\) = √0.19 / (0.9 × √200) = 0.0342 rad; \(\sigma_\tau\) = 0.0342/(2π × 5×10⁶) = 1.09 ns.
Q7Curvature fit with 128 elements (pitch 0.3 mm), 60 mm, 10 ns jitter. CRLB, and how many independent kernels to reach 0.5 m/s?
From the table of m32_sos_error_budget.m, 0.60 m/s at 5 ns, so 1.2 m/s at 10 ns (linear in σt). M = (1.2/0.5)² ≈ 6 kernels.
32.14Figures from the literature
Measured data behind the models of this module. Figure numbers were checked against the open preprints named in each entry (the published versions may number them differently); links only, no images reproduced.
Common mid-angle and the echo-position term: phantom and volunteer SoS maps
P. Stähli, M. Kuriakose, M. Frenz and M. Jaeger, "Improved forward model for quantitative pulse-echo speed-of-sound imaging," Ultrasonics 108, 106168 (2020); preprint arXiv:1902.10639. doi:10.1016/j.ultras.2020.106168
Look at Fig. 1 (isochrones for different transmit/receive angle pairs: only pairs sharing a mid-angle keep their relative position), Figs. 4–6 (two-layer, four-layer and laterally varying phantoms with liver 1555 and fat 1420 m/s; rows: old model, CMA model, new model; columns: four a priori speeds) and Fig. 7 (volunteer abdominal wall and liver, old versus new model). Why: it is the measured version of Sections 32.4–32.5: the gain from the CMA pairing, the extra gain from the echo-position term, and the dependence on the a priori mean.
CUTE with a convex probe: liver phantom, volunteer and the a priori speed
M. Jaeger, P. Stähli, N. Korta Martiartu, P. Salemi Yolgunlu, T. Frappart, C. Fraschini and M. Frenz, "Pulse-echo speed-of-sound imaging using convex probes," Phys. Med. Biol. (2022); preprint arXiv:2202.10633. doi:10.1088/1361-6560/ac96c6
Look at Fig. 5 (four-layer liver phantom: B-mode, SoS maps for two beamforming grids and two regularizations, depth profiles), Fig. 6 (volunteer liver, about 1580 m/s superficially), Fig. 8 (images for maximum angle spreads of 22, 6 and 3 steps) and Figs. 9–10 (phantom and in vivo maps for a priori speeds from 1510 to 1590 m/s). Why: Fig. 8 is Demo 32.4's θmax slider on real data, and Figs. 9–10 show the blind spot for the mean: robust in the phantom, up to about 100 m/s of spread below 60 mm in vivo.
Learned sound-speed inversion from raw channel data
M. Feigin, D. Freedman and B. W. Anthony, "A deep learning framework for single-sided sound speed inversion in medical ultrasound," IEEE Trans. Biomed. Eng. 67(4), 1142–1151 (2020); preprint arXiv:1810.00322 (figure numbers below follow the preprint). doi:10.1109/TBME.2019.2931195
Look at Fig. 6 (16 simulated test cases: reference versus three-plane-wave network output), Fig. 7 (absolute error for one and three plane waves), Fig. 8 (polyurethane phantom with an inclusion: B-mode, ground truth and reconstructions) and Fig. 10 (neck cross-section in vivo). Why: compare the clean simulated recoveries with the artefacts on the phantom: the domain gap of Section 32.6 in one page.
Differentiable-beamforming autofocus with a common-midpoint phase loss
W. Simson, L. Zhuang, B. N. Frey, S. J. Sanabria, J. J. Dahl and D. Hyun, "Ultrasound autofocusing: common midpoint phase error optimization via differentiable beamforming," arXiv:2410.03008 (version 3). Earlier work: W. Simson et al., "Differentiable beamforming for ultrasound autofocusing," MICCAI 2023, LNCS 14229, 428–437. doi:10.1007/978-3-031-43999-5_41
Look at Fig. 1 (straight-ray model of two common-midpoint subaperture pairs at lag 4 and their regions of support), Fig. 3 (simulated inclusion: lag-1 midpoint-offset phase error versus CMPE, at constant and correct speed), Fig. 5 (in vivo rat liver before and after autofocusing, with CMPE maps and coherence) and Fig. 7 (estimated versus calibrated phantom speeds). Why: Fig. 1 is (32.12) drawn by the authors, and Fig. 7 is the honest error budget: 8–14 m/s below calibrated values in layered and commercial phantoms.
32.15Go deeper
- M. E. Anderson and G. E. Trahey, "The direct estimation of sound speed using pulse-echo ultrasound," J. Acoust. Soc. Am. 104(5), 3099–3106 (1998). doi:10.1121/1.423889. Average speed from the arrival-time profile.
- C. H. Dix, "Seismic velocities from surface measurements," Geophysics (1955). The RMS-velocity moveout and the interval formula of (32.6).
- M. Jakovljevic, S. Hsieh, R. Ali, G. Chau, D. Hyun and J. J. Dahl, "Local speed of sound estimation in tissue using pulse-echo ultrasound: model-based approach," J. Acoust. Soc. Am. 144, 254–266 (2018). Average-to-local in two-layer media.
- M. Imbault, A. Faccinetto, B.-F. Osmanski, A. Tissier, T. Deffieux, J.-L. Gennisson, V. Vilgrain and M. Tanter, "Robust sound speed estimation for ultrasound-based hepatic steatosis assessment," Phys. Med. Biol. (2017). doi:10.1088/1361-6560/aa6226. Liver speed against MRI-PDFF and biopsy (open access).
- M. Jaeger, K. G. Held, S. E. Peeters, S. Preisser, M. Grünig and M. Frenz, "Computed ultrasound tomography in echo mode for imaging speed of sound using pulse-echo sonography: proof of principle," Ultrasound Med. Biol. 41(1), 235–250 (2015). doi:10.1016/j.ultrasmedbio.2014.05.019. The original CUTE paper: 0.6 % contrast resolution, 1 mm lateral by 3 mm axial.
- S. J. Sanabria, E. Ozkan, M. Rominger and O. Goksel, "Spatial domain reconstruction for imaging speed-of-sound with pulse-echo ultrasound: simulation and in vivo study," Phys. Med. Biol. 63(21) (2018). doi:10.1088/1361-6560/aae2fb.
- R. Ali, T. Brevett, D. Hyun, L. L. Brickson and J. J. Dahl, "Distributed aberration correction techniques based on tomographic sound speed estimates," IEEE Trans. Ultrason. Ferroelectr. Freq. Control (2022); R. Ali et al., "Sound speed estimation for distributed aberration correction in laterally varying media," IEEE Trans. Comput. Imaging (2023). From sound-speed maps back to delays (Module 33).
- R. Ali, "Sound speed estimation and phase-aberration correction for medical ultrasound imaging," Ph.D. thesis, Stanford University (2021). Includes the groundwork for wave-equation migration velocity analysis.
- IEEE IUS 2026 QUASOS challenge, final scores: UW Quantitative Ultrasound Lab page.
- Lab cross-links: coherence and the van Cittert–Zernike theorem (Module 07); delay estimation (Module 11); CRLB (Module 12); Tikhonov, resolution matrices and limited-angle SoS tomography (Module 13); autofocus and cycle skipping (Module 14); QUS (Module 27); CF and SLSC (Module 25); elastography and ULM, which inherit the speed (Modules 30, 31); aberration correction (Module 33).