torchbp.autofocus module

torchbp.autofocus.C0 = 299792458.0

Speed of light in vacuum [m/s]. Must match kC0 in csrc/cpu/util.h.

torchbp.autofocus.bp_cart_grad_minimum_entropy(data, data_time, pos, fc, r_res, grid, wa, tx_norm=None, max_steps=100, lr_max=10000, d0=0, pos_reg=1, lr_reduce=0.8, verbose=True, convergence_limit=0.01, max_step_limit=0.25, grad_limit_quantile=0.9, fixed_pos=0, data_fmod=0)[source]

Minimum entropy autofocus optimization autofocus.

Wrapper around minimum_entropy_autofocus.

Parameters:
  • data (Tensor) – Radar data.

  • data_time (Tensor) – Recording time of each data sample.

  • pos (Tensor) – Position at each data sample.

  • fc (float) – RF frequency in Hz.

  • r_res (float) – Range bin resolution in data (meters). For FMCW radar: c/(2*bw*oversample), where c is speed of light, bw is sweep bandwidth, and oversample is FFT oversampling factor.

  • grid (PolarGrid or dict) – Grid definition. Correct definition depends on the radar image function.

  • wa (Tensor) – Azimuth windowing function. Should be applied to data already, used for scaling gradient.

  • tx_norm (Tensor) – Radar image is divided by this tensor before calculating entropy. If None no division is done.

  • max_steps (int) – Maximum number of optimization steps.

  • lr_max (float) – Maximum learning rate. Too large learning rate is scaled automatically.

  • d0 (float) – Zero range correction.

  • pos_reg (float) – Position regularization value.

  • lr_reduce (float) – Learning rate is multiplied with this value if new entropy is larger than previously.

  • verbose (bool) – Print progress during optimization.

  • convergence_limit (float) – If maximum position change is below this value stop optimization. Units in wavelengths.

  • max_step_limit (float) – Maximum step size in wavelengths.

  • grad_limit_quantile (float) – Quantile used for maximum step size calculation. 0 to 1 range.

  • fixed_pos (int) – First fixed_pos positions are kept fixed and are not optimized.

  • data_fmod (float) – Range modulation frequency applied to input data.

Returns:

  • sar_img (Tensor) – Optimized radar image.

  • origin (Tensor) – Mean of position tensor.

  • pos (Tensor) – Platform position.

  • step (int) – Number of steps.

Return type:

tuple[Tensor, Tensor, Tensor, int]

torchbp.autofocus.bp_polar_grad_minimum_entropy(data, data_time, pos, fc, r_res, grid, wa, tx_norm=None, max_steps=100, lr_max=10000, d0=0, pos_reg=1, lr_reduce=0.8, verbose=True, convergence_limit=0.01, max_step_limit=0.25, grad_limit_quantile=0.9, fixed_pos=0, data_fmod=0)[source]

Minimum entropy autofocus optimization autofocus.

Wrapper around minimum_entropy_autofocus.

Parameters:
  • data (Tensor) – Radar data.

  • data_time (Tensor) – Recording time of each data sample.

  • pos (Tensor) – Position at each data sample.

  • fc (float) – RF frequency in Hz.

  • r_res (float) – Range bin resolution in data (meters). For FMCW radar: c/(2*bw*oversample), where c is speed of light, bw is sweep bandwidth, and oversample is FFT oversampling factor.

  • grid (PolarGrid or dict) – Grid definition. Correct definition depends on the radar image function.

  • wa (Tensor) – Azimuth windowing function. Should be applied to data already, used for scaling gradient.

  • tx_norm (Tensor) – Radar image is divided by this tensor before calculating entropy. If None no division is done.

  • max_steps (int) – Maximum number of optimization steps.

  • lr_max (float) – Maximum learning rate. Too large learning rate is scaled automatically.

  • d0 (float) – Zero range correction.

  • pos_reg (float) – Position regularization value.

  • lr_reduce (float) – Learning rate is multiplied with this value if new entropy is larger than previously.

  • verbose (bool) – Print progress during optimization.

  • convergence_limit (float) – If maximum position change is below this value stop optimization. Units in wavelengths.

  • max_step_limit (float) – Maximum step size in wavelengths.

  • grad_limit_quantile (float) – Quantile used for maximum step size calculation. 0 to 1 range.

  • fixed_pos (int) – First fixed_pos positions are kept fixed and are not optimized.

  • data_fmod (float) – Range modulation frequency applied to input data.

Returns:

  • sar_img (Tensor) – Optimized radar image.

  • origin (Tensor) – Mean of position tensor.

  • pos (Tensor) – Platform position.

  • step (int) – Number of steps.

Return type:

tuple[Tensor, Tensor, Tensor, int]

torchbp.autofocus.gpga(img, data, pos, fc, r_res, grid, algorithm='bp', image_opts=None, window_width=None, max_iters=10, window_exp=0.7, min_window=5, d0=0.0, target_threshold_db=20, isolation_db=6.0, isolation_guard=5, isolation_window=30, beam_gate=0.2, remove_trend=True, estimator='pd', lowpass_window='boxcar', eps=1e-06, interp_method='linear', att=None, g=None, g_extent=None, data_fmod=0, dem=None)[source]

Generalized phase gradient autofocus. [1]

Works with any image formation algorithm in the library and with both polar and Cartesian grids. The grid type is detected automatically and the image formation algorithm is selected with algorithm.

Parameters:
  • img (Tensor or None) – Complex input image. Shape should be: [Range, azimuth] for a polar grid or [x, y] for a Cartesian grid. If None image is generated from the data.

  • data (Tensor or LazyData) – Range compressed input data. Shape should be [nsweeps, samples]. A torchbp.data.LazyData source is read in bounded chunks by the phase estimation stage and streamed leaf-by-leaf by algorithm="ffbp", so data larger than memory can be focused; other algorithms accept a lazy source but materialize it fully on every image formation. A lazy source is re-read on every iteration: if it has an expensive transform pipeline (range compression of raw sweeps), wrap it in torchbp.data.CachedData so the pipeline runs only once per sweep.

  • pos (Tensor) – Position of the platform at each data point. Shape should be [nsweeps, 3].

  • fc (float) – RF center frequency in Hz.

  • r_res (float) – Range bin resolution in data (meters). For FMCW radar: c/(2*bw*oversample), where c is speed of light, bw is sweep bandwidth, and oversample is FFT oversampling factor.

  • grid (PolarGrid, CartesianGrid or dict) –

    Image grid definition. Can be:

    • PolarGrid object: PolarGrid(r_range=(r0, r1), theta_range=(theta0, theta1), nr=nr, ntheta=ntheta) (theta is sin of angle, -1 to 1 for 180 degree view), or the equivalent dict {“r”: …, “theta”: …, “nr”: …, “ntheta”: …}.

    • CartesianGrid object: CartesianGrid(x_range=(x0, x1), y_range=(y0, y1), nx=nx, ny=ny), or the equivalent dict {“x”: …, “y”: …, “nx”: …, “ny”: …}.

  • algorithm (str) – Image formation algorithm. For a polar grid: “bp” (torchbp.ops.backprojection_polar_2d(), default), “ffbp” (torchbp.ops.ffbp()) or “afbp” (torchbp.ops.afbp()). For a Cartesian grid: “bp” (torchbp.ops.backprojection_cart_2d(), default), “cfbp” (torchbp.ops.cfbp()) or “cfbp_adaptive” (torchbp.ops.cfbp_adaptive()).

  • image_opts (dict or None) – Extra keyword arguments for the image formation algorithm, merged over per-algorithm defaults. “ffbp” defaults to {“stages”: 5, “oversample_r”: 1.4, “oversample_theta”: 1.4}; “cfbp”/”cfbp_adaptive” default to {“stages”: 4}; “afbp” requires {“nsub”: N}. The range interpolation method of the data is also set here, e.g. {“interp_method”: (“knab”, 6, 2.0)} for polar “bp” or {“data_interp_method”: (“knab”, 6, 2.0)} for “ffbp”/”afbp”.

  • window_width (int or None) – Initial low-pass filter window width in samples. None for initial maximum size.

  • max_iters (int) – Maximum number of iterations.

  • window_exp (float) – Exponent on window_width decrease for each iteration.

  • min_window (int) – Minimum window size.

  • d0 (float) – Zero range correction.

  • target_threshold_db (float) – Filter out targets that are this many dB below the maximum amplitude target.

  • isolation_db (float) – Reject targets whose peak is less than this many dB above the mean amplitude of the surrounding cells along the second image axis (excluding a guard band around the peak). Screens out targets embedded in extended clutter, e.g. building walls, that violate the point-target assumption. 0 disables the screen. If no target passes the screen, selection falls back to amplitude only.

  • isolation_guard (int) – Half-width in pixels of the guard band around the peak excluded from the clutter estimate.

  • isolation_window (int) – Half-width in pixels of the clutter estimation window.

  • beam_gate (float) – When the antenna pattern (att, g, g_extent) is given, target samples whose two-way antenna amplitude is below beam_gate times that target’s maximum are zeroed and excluded from the phase estimate. This makes the estimate robust to discontinuous target illumination (stripmap-like collections), where out-of-beam samples contain unrelated clutter from the same range ring.

  • remove_trend (bool) – Remove linear trend in phase correction.

  • estimator (str) – Estimator to use. See pga_estimator function for possible choices. With discontinuous illumination (antenna weighting on a stripmap-like collection) “wls” is recommended: “pd” accumulates a drift as targets enter and leave the beam.

  • lowpass_window (str) – FFT window to use for lowpass filtering. See scipy.get_window for syntax.

  • eps (float) – Minimum weight for weighted PGA.

  • interp_method (str) – Interpolation method “linear”: linear interpolation. (“lanczos”, N): Lanczos interpolation with order 2*N+1.

  • att (Tensor) – Antenna rotation tensor. [Roll, pitch, yaw]. Only yaw is used and only if beamwidth < Pi to filter out data outside the antenna beam.

  • g (Tensor or None) – Square-root of two-way antenna gain in spherical coordinates, shape: [elevation, azimuth]. If TX antenna equals RX antenna, then this should be just antenna gain. (0, 0) angle is at the beam center. When given together with att and g_extent, the pattern is also used to weight the per-target phase history samples (see beam_gate).

  • g_extent (list or None) – List of [g_el0, g_az0, g_el1, g_az1]. g_el0, g_el1 are grx and gtx elevation axis start and end values. Units in radians. -pi/2 + +pi/2 if including data over the whole sphere. g_az0, g_az1 are grx and gtx azimuth axis start and end values. Units in radians. -pi to +pi if including data over the whole sphere. Antenna pattern arguments are only supported by the polar algorithms.

  • data_fmod (float) – Range modulation frequency applied to input data.

  • dem (Tensor or None) – Digital elevation model sampled on the image grid. Shape [dem_nr, dem_ntheta], covering the same extent as grid; can be coarser than the image grid (bilinearly interpolated). Values are pixel z coordinates in the same frame as pos. Used both for the image formation and for the autofocus target positions. Only supported with a polar grid. See torchbp.util.dem_to_polar() for resampling a Cartesian DEM onto the polar grid. If None (default) targets are assumed to lie on the z=0 plane.

Return type:

tuple[Tensor, Tensor]

References

[1]

A. Evers and J. A. Jackson, “A Generalized Phase Gradient Autofocus Algorithm,” in IEEE Transactions on Computational Imaging, vol. 5, no. 4, pp. 606-619, Dec. 2019.

Returns:

  • img (Tensor) – Focused SAR image.

  • phi (Tensor) – Solved phase error.

Parameters:
  • img (Tensor | None)

  • data (Tensor | LazyData)

  • pos (Tensor)

  • fc (float)

  • r_res (float)

  • grid (PolarGrid | CartesianGrid | dict)

  • algorithm (str)

  • image_opts (dict | None)

  • window_width (int | None)

  • max_iters (int)

  • window_exp (float)

  • min_window (int)

  • d0 (float)

  • target_threshold_db (float)

  • isolation_db (float)

  • isolation_guard (int)

  • isolation_window (int)

  • beam_gate (float)

  • remove_trend (bool)

  • estimator (str)

  • lowpass_window (str)

  • eps (float)

  • interp_method (str)

  • att (Tensor | None)

  • g (Tensor | None)

  • g_extent (list | None)

  • data_fmod (float)

  • dem (Tensor | None)

Return type:

tuple[Tensor, Tensor]

torchbp.autofocus.gpga_tde(img, data, pos, fc, r_res, grid, azimuth_divisions, range_divisions, algorithm='bp', image_opts=None, window_width=None, rms_error_limit=0.05, max_iters=20, window_exp=0.7, min_window=5, d0=0.0, target_threshold_db=20, isolation_db=6.0, isolation_guard=5, isolation_window=30, beam_gate=0.2, remove_trend=True, lowpass_window='boxcar', eps=1e-06, interp_method='linear', estimate_z=True, solve_threshold=0.003, att=None, g=None, g_extent=None, verbose=False, data_fmod=0, dem=None)[source]

Generalized phase gradient autofocus [1] with time-domain error (TDE) 3D position estimation.

Works with any image formation algorithm in the library and with both polar and Cartesian grids (see gpga() for algorithm / image_opts / grid).

Estimates 3D position error by dividing the image into subimages, estimating slant range error to each subimage, and then solving for 3D position error from slant range errors. [2]

Z-axis estimation requires variable look angles in the image. Set estimate_z to False if this is not the case, for example ground based radar.

Parameters:
  • img (Tensor or None) – Complex input image. Shape should be: [Range, azimuth]. If None image is generated from the data.

  • data (Tensor or LazyData) – Range compressed input data. Shape should be [nsweeps, samples]. A torchbp.data.LazyData source is supported like in gpga(): chunked estimation reads, streaming image formation with algorithm="ffbp", full materialization with the other algorithms, re-read on every iteration (consider torchbp.data.CachedData for expensive pipelines).

  • pos (Tensor) – Position of the platform at each data point. Shape should be [nsweeps, 3].

  • fc (float) – RF center frequency in Hz.

  • r_res (float) – Range bin resolution in data (meters). For FMCW radar: c/(2*bw*oversample), where c is speed of light, bw is sweep bandwidth, and oversample is FFT oversampling factor.

  • grid (PolarGrid, CartesianGrid or dict) – Image grid definition (polar or Cartesian). See gpga().

  • azimuth_divisions (int) – Number of divisions for local images in azimuth direction.

  • range_divisions (int) – Number of divisions for local images in range direction.

  • algorithm (str) – Image formation algorithm. See gpga().

  • image_opts (dict or None) – Extra keyword arguments for the image formation algorithm. See gpga().

  • window_width (int or None) – Initial low-pass filter window width in samples. None for initial maximum size.

  • rms_error_limit (float) – Phase RMS error limit in radians for stopping the optimization iteration.

  • max_iters (int) – Maximum number of iterations.

  • window_exp (float) – Exponent on window_width decrease for each iteration.

  • min_window (int) – Minimum window size.

  • d0 (float) – Zero range correction.

  • target_threshold_db (float) – Filter out targets that are this many dB below the maximum amplitude target.

  • isolation_db (float) – Reject targets whose peak is less than this many dB above the mean amplitude of the surrounding cells along the second image axis (excluding a guard band around the peak). Screens out targets embedded in extended clutter, e.g. building walls, that violate the point-target assumption. 0 disables the screen. If no target in a block passes the screen, selection falls back to amplitude only.

  • isolation_guard (int) – Half-width in pixels of the guard band around the peak excluded from the clutter estimate.

  • isolation_window (int) – Half-width in pixels of the clutter estimation window.

  • beam_gate (float) – When the antenna pattern (att, g, g_extent) is given, target samples whose two-way antenna amplitude is below beam_gate times that target’s maximum are zeroed and excluded from the phase estimate, and each block’s contribution to the position solve is weighted per sweep by its illumination. This makes the estimate robust to discontinuous target illumination (stripmap-like collections), where out-of-beam samples contain unrelated clutter from the same range ring.

  • remove_trend (bool) – Remove linear trend in phase correction.

  • lowpass_window (str) – FFT window to use for lowpass filtering. See scipy.get_window for syntax.

  • eps (float) – Minimum weight for weighted PGA.

  • interp_method (str) – Interpolation method “linear”: linear interpolation. (“lanczos”, N): Lanczos interpolation with order 2*N+1.

  • estimate_z (bool) – Estimate Z-axis position error. Default is True.

  • solve_threshold (float) – Relative eigenvalue threshold of the per-sweep position solve. Directions of the per-sweep normal matrix with eigenvalues below this fraction of the largest eigenvalue over all sweeps are considered unobservable at that sweep and get zero position update. Raise it if unobservable directions (e.g. along-track at broadside with a narrow beam) accumulate noise; lower it if a weakly observed direction that should be estimated is being suppressed.

  • att (Tensor) – Antenna rotation tensor. [Roll, pitch, yaw]. Only yaw is used and only if beamwidth < Pi to filter out data outside the antenna beam.

  • g (Tensor or None) – Square-root of two-way antenna gain in spherical coordinates, shape: [elevation, azimuth]. If TX antenna equals RX antenna, then this should be just antenna gain. (0, 0) angle is at the beam center. When given together with att and g_extent, the pattern is also used to weight the per-target phase history samples and the per-sweep position solve (see beam_gate).

  • g_extent (list or None) – List of [g_el0, g_az0, g_el1, g_az1]. g_el0, g_el1 are grx and gtx elevation axis start and end values. Units in radians. -pi/2 + +pi/2 if including data over the whole sphere. g_az0, g_az1 are grx and gtx azimuth axis start and end values. Units in radians. -pi to +pi if including data over the whole sphere. Antenna pattern arguments are only supported by the polar algorithms.

  • verbose (bool) – Print progress stats.

  • data_fmod (float) – Range modulation frequency applied to input data.

  • dem (Tensor or None) – Digital elevation model sampled on the image grid. Shape [dem_nr, dem_ntheta], covering the same extent as grid; can be coarser than the image grid (bilinearly interpolated). Values are pixel z coordinates in the same frame as pos. Used for the image formation, the autofocus target positions and the block-center geometry of the position solve. Only supported with a polar grid. See torchbp.util.dem_to_polar() for resampling a Cartesian DEM onto the polar grid. If None (default) targets are assumed to lie on the z=0 plane.

Return type:

tuple[Tensor, Tensor]

References

[1]

A. Evers and J. A. Jackson, “A Generalized Phase Gradient Autofocus Algorithm,” in IEEE Transactions on Computational Imaging, vol. 5, no. 4, pp. 606-619, Dec. 2019.

[2]

Z. Ding et al., “An Autofocus Approach for UAV-Based Ultrawideband Ultrawidebeam SAR Data With Frequency-Dependent and 2-D Space-Variant Motion Errors,” in IEEE Transactions on Geoscience and Remote Sensing, vol. 60, pp. 1-18, 2022, Art no. 5203518.

Returns:

  • img (Tensor) – Focused SAR image.

  • pos_new (Tensor) – Solved 3D position error.

Parameters:
  • img (Tensor | None)

  • data (Tensor | LazyData)

  • pos (Tensor)

  • fc (float)

  • r_res (float)

  • grid (PolarGrid | CartesianGrid | dict)

  • azimuth_divisions (int)

  • range_divisions (int)

  • algorithm (str)

  • image_opts (dict | None)

  • window_width (int | None)

  • rms_error_limit (float)

  • max_iters (int)

  • window_exp (float)

  • min_window (int)

  • d0 (float)

  • target_threshold_db (float)

  • isolation_db (float)

  • isolation_guard (int)

  • isolation_window (int)

  • beam_gate (float)

  • remove_trend (bool)

  • lowpass_window (str)

  • eps (float)

  • interp_method (str)

  • estimate_z (bool)

  • solve_threshold (float)

  • att (Tensor | None)

  • g (Tensor | None)

  • g_extent (list | None)

  • verbose (bool)

  • data_fmod (float)

  • dem (Tensor | None)

Return type:

tuple[Tensor, Tensor]

torchbp.autofocus.insar_rme_blocksvd(data_s, pos_s, img_m, fc, r_res, grid_polar, n_az_blocks=32, n_r_blocks=16, d0=0.0, data_fmod=0.0, row_weight='coherence', align_blocks=True, aperture_mask=True, aperture_pad=1.0, phi_lowpass=0, spatial_coherence=None, return_alpha=False, return_magnitude=False, return_complex=False, verbose=False)[source]

Closed-form block-coherent InSAR residual motion error estimation.

Estimates per-slave-sweep range-direction position errors by combining per-block coherent statistics computed against an existing master image.

Notes

The image is tiled into n_r_blocks x n_az_blocks non-overlapping blocks. For each block b:

  1. The per-block per-sweep statistic is the inner product of the slave data’s backprojection footprint at the block’s pixels against the existing master image patch: alpha^{(b)}_m = Sum_k conj(img_m[pix_k]) * data_s[m, r_idx(pix_k, m)] * exp(j k R(pix_k, m)), computed by the fused torchbp.ops.blocksvd_alpha() kernel (master is never demodulated to targets and the per-pixel footprint matrix is never materialized).

  2. This is the closed-form maximizer (over per-sweep phase) of the block’s coherent inner product, with the master image acting as the optimal pixel weighting.

The per-block alpha-vectors are then combined into a global per-sweep phase. Each block has an unknown complex constant c_b (per-block baseline + topo phase). With align_blocks=True, each block’s alpha is divided by its mean phase to absorb c_b, and the aligned alphas are coherently summed:

alpha_combined_m = Sum_b alpha^{(b)}_m / e^{j angle(Sum_m alpha^{(b)}_m)}
phi_m = +angle(alpha_combined_m) (data is corrected by exp(-j phi))

The corrected slave position is pos_s + [dr_m, 0, 0] (range-only, in the slave’s local frame where the +X axis is the radar look direction).

Parameters:
  • data_s (Tensor [nsweeps_s, nsamples]) – Range-compressed slave data.

  • pos_s (Tensor [nsweeps_s, 3]) – Slave platform positions in the slave’s local frame.

  • img_m (Tensor [nr, ntheta] or [1, nr, ntheta]) – Master image already formed on grid_polar. Must be on the same grid as the slave will be reformed on; no master/slave image interpolation is performed.

  • fc (float) – RF center frequency in Hz.

  • r_res (float) – Range bin resolution in data (meters).

  • grid_polar (PolarGrid or dict) – Polar grid definition.

  • n_az_blocks (int) – Image tiling. The total number of blocks is the product. Use enough azimuth blocks to give multi-block coverage of every sweep (a few times nsweeps_s / aperture_length); a small number of range blocks (5–20) is enough for diversity. Block size should be small enough that topographic phase is approximately constant within a block (otherwise per-block coherent integration cancels).

  • n_r_blocks (int) – Image tiling. The total number of blocks is the product. Use enough azimuth blocks to give multi-block coverage of every sweep (a few times nsweeps_s / aperture_length); a small number of range blocks (5–20) is enough for diversity. Block size should be small enough that topographic phase is approximately constant within a block (otherwise per-block coherent integration cancels).

  • d0 (float) – Zero range correction.

  • data_fmod (float) – Range modulation frequency applied to input data.

  • row_weight ("coherence" | "power" | "uniform") – Per-block row weight. “coherence” Weight be coherence. Recommended for real data. “power” divides by image power. “uniform” uses no weighting.

  • align_blocks (bool) – If True, divide each block’s alpha by its mean phase before combining. This absorbs the per-block complex constant c_b (baseline / sub-pixel position) and is essential when topographic phase varies across the image.

  • aperture_mask (bool) – If True (recommended), zero out per-block alpha entries for slave sweeps outside the block’s synthetic-aperture window.

  • aperture_pad (float) – Multiplier on the polar grid’s angular extent used by aperture_mask. 1.0 uses the exact grid extent; >1 widens the per-block window.

  • spatial_coherence (Tensor [nr, ntheta] or None) – Per-pixel coherence map (e.g. from torchbp.ops.power_coherence_2d) used to downweight decorrelated regions. The map is squared (coh**2 weighting) and multiplied into the master image patch before forming each block’s alpha, so contributions from vegetation or shadow areas are suppressed pixel-by-pixel.

  • phi_lowpass (int) – If > 0, lowpass-filter the recovered phase along the sweep axis with a Hamming window of this width (in samples). Use a value much smaller than nsweeps_s and at least a few times smaller than the expected RME bandwidth. 0 disables filtering.

  • return_alpha (bool) – If True, also return the [nblocks, nsweeps_s] alpha matrix for diagnostics.

  • return_complex (bool) – If True, also return the raw per-sweep coherent sum v before any lowpass filtering or unwrapping. Used by insar_rme_blocksvd_strata() to do its own phase post-processing.

  • verbose (bool) – Print progress.

  • return_magnitude (bool)

Returns:

  • pos_s_new (Tensor [nsweeps_s, 3]) – Corrected slave positions (only the range component is modified).

  • phi (Tensor [nsweeps_s]) – Estimated per-sweep RME phase, zero-mean.

  • v_mag (Tensor [nsweeps_s], optional) – Returned only when return_magnitude=True.

  • alpha (Tensor [nblocks, nsweeps_s], optional) – Returned only when return_alpha=True.

  • v_complex (Tensor [nsweeps_s], optional) – Returned only when return_complex=True. The RME phase is -angle(v_complex) (before mean removal and unwrapping).

Return type:

tuple[Tensor, Tensor]

torchbp.autofocus.insar_rme_blocksvd_strata(data_s, pos_s, img_m, fc, r_res, grid_polar, n_strata=8, n_az_blocks_per_strata=32, strata_spacing='elevation', estimate_z=False, d0=0.0, data_fmod=0.0, phi_lowpass=0, delta_lowpass=0, z_lowpass=None, ls_reg=0.3, robust_iters=2, spatial_coherence=None, return_phi_strata=False, verbose=False, altitude=None)[source]

Stratified closed-form InSAR RME with optional XZ decomposition.

Splits the polar grid into n_strata range bands, runs an independent insar_rme_blocksvd per band to obtain a high-SNR per-sweep slant-range error estimate Delta r_s(m), then per sweep solves a small (K_strata x n_axes) weighted linear system using the look vector from the slave platform to each strata centroid. The result is a per-sweep position correction (XZ or X depending on estimate_z).

The per-sweep system is solved as a ridge-regularized weighted least squares with optional Huber reweighting across strata. The X and Z columns of the system are strongly anti-correlated (both cos(el) and sin(el) are monotonic in range), so without regularization differential noise between strata is amplified into large anti-correlated X/Z errors. The ridge shrinks the solution toward zero where all strata have low SNR, and the Huber pass rejects strata whose residuals are inconsistent with the rest (layover, decorrelated region).

Same closed-form / no-master-GPGA / no-master-interpolation properties as insar_rme_blocksvd. Compared to the plain blocksvd:

  • X-only typically yields a more accurate X correction (per-strata blocksvd is better-conditioned and the LS averages across strata).

  • XZ can recover a real Z error when the geometry has enough elevation diversity (significant variation of sin(el) across the range swath, i.e. low altitude / wide range, or tall platform / short range).

Parameters:
  • data_s (Tensor) – Same as insar_rme_blocksvd().

  • pos_s (Tensor) – Same as insar_rme_blocksvd().

  • img_m (Tensor) – Same as insar_rme_blocksvd().

  • fc (float) – Same as insar_rme_blocksvd().

  • r_res (float) – Same as insar_rme_blocksvd().

  • grid_polar (PolarGrid | dict) – Same as insar_rme_blocksvd().

  • n_strata (int) – Number of range strata. Should be >= 2 for XZ mode (more strata → more LS averaging, but each strata has fewer pixels).

  • n_az_blocks_per_strata (int) – Number of azimuth blocks per strata, passed to the per-strata insar_rme_blocksvd() call.

  • estimate_z (bool) – If True, also solve for Z position error. Requires n_strata >= 2 and meaningful elevation-angle diversity across strata.

  • d0 (float) – Forwarded to per-strata insar_rme_blocksvd().

  • data_fmod (float) – Forwarded to per-strata insar_rme_blocksvd().

  • spatial_coherence (Tensor | None) – Forwarded to per-strata insar_rme_blocksvd().

  • phi_lowpass (int) – If > 1, lowpass the per-strata phase with a Hamming window of this width (sweeps) and use the result as the unwrapping reference only: the full-band phase is kept as unwrap(lowpass(phi)) + wrap(phi - lowpass(phi)). This makes the unwrap robust to per-sweep phase noise without discarding high-frequency RME content. If 0, the raw phase is unwrapped directly, which is fragile at low SNR.

  • delta_lowpass (int) – If > 0, Hamming-window lowpass after the LS. Useful to suppress LS noise on Z when its conditioning is marginal.

  • z_lowpass (int or None) – If > 1, additional Hamming-window lowpass applied to the Z correction only. Z is observed through the band-differential of the strata phases, which is much noisier than their common mode, so it tolerates a tighter bandwidth than X. None (default) uses phi_lowpass; 0 disables.

  • ls_reg (float) – Ridge regularization of the per-sweep least squares, relative to the median per-(strata, sweep) weight. Shrinks the correction toward zero where all strata have low SNR. Set to 0 to disable (weights then revert to per-sweep normalization).

  • robust_iters (int) – Number of Huber IRLS reweighting passes over the per-sweep LS. Strata whose weighted residuals exceed 1.345 times the global MAD scale are downweighted proportionally, rejecting decorrelated or layover-dominated strata. 0 disables.

  • return_phi_strata (bool) – If True, also return the [n_strata, nsweeps] per-strata phase matrix for diagnostics.

  • verbose (bool) – Print per-strata progress.

  • altitude (float or None) – Sensor altitude for slant-range grids (BP origin at sensor altitude, pos_s z ≈ 0). When set, uses slant-range geometry for elevation strata (sin_el = H/r) and look vectors. When None (default), altitude is inferred from pos_s[:, 2] and ground-range geometry is used (sin_el = H/sqrt(r**2+H**2)).

  • strata_spacing (str)

Returns:

  • pos_s_new (Tensor [nsweeps, 3]) – Corrected slave positions; X is always corrected, Z corrected only when estimate_z=True.

  • delta (Tensor [nsweeps, 3]) – Per-sweep XYZ correction added to pos_s. Non-estimated axes are zero.

  • phi_strata (Tensor [n_strata, nsweeps], optional) – Returned when return_phi_strata=True.

Return type:

tuple[Tensor, Tensor]

torchbp.autofocus.insar_rme_multisquint(img_m, img_s, pos_s, fc, grid_polar, n_looks=32, look_width=2.0, n_r_bands=4, band_spacing='elevation', estimate_z=False, n_z_basis=8, aperture_mask=True, aperture_pad=1.0, patch_theta=None, spatial_coherence=None, data_s=None, r_res=None, max_iters=1, d0=0.0, data_fmod=0.0, dealias=False, alias_fmod=0.0, delta_lowpass=0, ls_reg=0.1, remove_trend=True, altitude=None, return_phi_bands=False, verbose=False)[source]

Multisquint InSAR residual motion error estimation [1] [2].

Image-domain method: in a polar-grid backprojection image the azimuth (theta) spectrum maps linearly to along-track platform position, f_theta = -(2/wl) * cos(el) * y, so squinted sub-looks are bandpass windows of the theta-axis FFT. For each range band and each adjacent pair of looks, the double difference of the per-look interferograms

D_j = (L_m_j * conj(L_s_j)) * conj(L_m_(j-1) * conj(L_s_(j-1)))

cancels the look-independent topographic / baseline phase, leaving the difference of the slave RME phase between the two look positions. Coherently averaging D_j over the band and integrating the steps gives the per-band slant-range error profile along the track; a per-sweep weighted least squares across range bands separates X (and optionally Z) position error using elevation angle diversity, as in insar_rme_blocksvd_strata().

Because the observable is a phase difference between adjacent looks, no phase unwrapping is needed as long as the RME phase changes by less than pi between look centers. Cost is a few FFTs per look — no backprojection of slave data is required (unless max_iters > 1).

The master image is assumed to be focused (autofocused first) and both images must be formed on the same polar grid in the same coordinate frame. Constant slant-range error is unobservable (absorbed into the baseline estimate); the returned correction is zero-mean per axis. Along-track (Y) error is not estimated; its first-order effect on the look phases averages out over a symmetric azimuth extent.

Parameters:
  • img_m (Tensor) – Master image [nr, ntheta] formed on grid_polar. Assumed free of motion error.

  • img_s (Tensor) – Slave image [nr, ntheta] formed on the same grid with positions pos_s.

  • pos_s (Tensor) – Slave platform positions [nsweeps, 3] in the backprojection frame. Along-track (Y) coordinates must be ascending.

  • fc (float) – RF center frequency in Hz.

  • grid_polar (PolarGrid or dict) – Polar grid definition.

  • n_looks (int) – Number of squinted looks across the along-track extent. The recovered error profile has n_looks samples along the track, interpolated to sweeps; RME components faster than nsweeps / (2 * n_looks) cycles per aperture are not resolved.

  • look_width (float) – Look bandwidth in units of look spacing. Wider looks have more spectral bins (less phase noise) but lower along-track resolution. The double differences are taken between looks ceil(look_width) apart so the differenced windows share no spectral bins; shared speckle content would bias the phase steps toward zero.

  • n_r_bands (int) – Number of range bands. Must be >= 2 for estimate_z.

  • band_spacing ("elevation" | "range") – Band edge spacing, see insar_rme_blocksvd_strata().

  • estimate_z (bool) – Also solve for Z position error. Requires elevation-angle diversity across the range swath.

  • n_z_basis (int) – Number of linear-interpolation basis knots for the Z error profile. Z is observed only through the band-differential of the look phases, which is noisier than their common mode; a coarse basis trades Z bandwidth for stability. Z components faster than n_z_basis / 2 cycles per aperture are not resolved.

  • aperture_mask (bool) – Zero out pixels outside a look’s angular aperture (using the grid theta extent as the beam proxy) when averaging the double differences.

  • aperture_pad (float) – Multiplier on the grid theta extent used by aperture_mask.

  • patch_theta (int or None) – Azimuth multilook patch length (pixels) applied to the per-look interferograms before double-differencing. None (default) chooses about one look azimuth-resolution cell. Must be small enough that topographic phase is approximately constant over the patch along theta.

  • spatial_coherence (Tensor [nr, ntheta] or None) – Optional per-pixel coherence map; squared and used as a pixel weight in the double-difference averages.

  • data_s (Tensor or None) – Range-compressed slave data [nsweeps, samples]. Only needed when max_iters > 1 to reform the slave image between iterations.

  • r_res (float or None) – Range bin resolution of data_s. Required when max_iters > 1.

  • max_iters (int) – Number of estimation iterations. Iterating reforms the slave image at the corrected positions, which sharpens the looks when the initial error is large.

  • d0 (float) – Backprojection parameters used to reform the slave image between iterations. Must match how img_s was formed.

  • data_fmod (float) – Backprojection parameters used to reform the slave image between iterations. Must match how img_s was formed.

  • dealias (bool) – Backprojection parameters used to reform the slave image between iterations. Must match how img_s was formed.

  • alias_fmod (float) – Backprojection parameters used to reform the slave image between iterations. Must match how img_s was formed.

  • delta_lowpass (int) – If > 0, Hamming-window lowpass of this width (sweeps) applied to the per-sweep correction.

  • ls_reg (float) – Ridge regularization of the per-step least squares, relative to the median double-difference weight. Shrinks the correction toward zero where all bands have low SNR (track edges).

  • remove_trend (bool) – Remove the weighted mean phase step per band before solving. This removes linear error trends (unobservable, absorbed into the baseline estimate) together with the deterministic baseline-induced ramp of the look phases, which is range-dependent and would otherwise leak into a slow X/Z drift.

  • altitude (float or None) – Sensor altitude for slant-range grids, see insar_rme_blocksvd_strata(). None infers altitude from pos_s[:, 2] and uses ground-range geometry.

  • return_phi_bands (bool) – Also return the per-band slant-range error phase interpolated to sweeps, shape [n_r_bands, nsweeps].

  • verbose (bool) – Print progress.

Return type:

tuple[Tensor, Tensor]

References

[1]

P. Prats and J. J. Mallorqui, “Estimation of azimuth phase undulations with multisquint multitemporal coregistration,” in IEEE Geoscience and Remote Sensing Letters, vol. 1, no. 4, pp. 268-271, Oct. 2004.

[2]

J. M. de Macedo, R. Scheiber and A. Moreira, “An Autofocus Approach for Residual Motion Errors With Application to Airborne Repeat-Pass SAR Interferometry,” in IEEE Transactions on Geoscience and Remote Sensing, vol. 46, no. 10, pp. 3151-3162, Oct. 2008.

Returns:

  • pos_s_new (Tensor [nsweeps, 3]) – Corrected slave positions; X always corrected, Z only when estimate_z=True.

  • delta (Tensor [nsweeps, 3]) – Total per-sweep XYZ correction added to pos_s. Non-estimated axes are zero.

  • phi_bands (Tensor [n_r_bands, nsweeps], optional) – Returned when return_phi_bands=True. Last iteration’s per-band RME phase.

Parameters:
  • img_m (Tensor)

  • img_s (Tensor)

  • pos_s (Tensor)

  • fc (float)

  • grid_polar (PolarGrid | dict)

  • n_looks (int)

  • look_width (float)

  • n_r_bands (int)

  • band_spacing (str)

  • estimate_z (bool)

  • n_z_basis (int)

  • aperture_mask (bool)

  • aperture_pad (float)

  • patch_theta (int | None)

  • spatial_coherence (Tensor | None)

  • data_s (Tensor | None)

  • r_res (float | None)

  • max_iters (int)

  • d0 (float)

  • data_fmod (float)

  • dealias (bool)

  • alias_fmod (float)

  • delta_lowpass (int)

  • ls_reg (float)

  • remove_trend (bool)

  • altitude (float | None)

  • return_phi_bands (bool)

  • verbose (bool)

Return type:

tuple[Tensor, Tensor]

torchbp.autofocus.minimum_entropy_grad_autofocus(f, data, data_time, pos, fc, r_res, grid, wa, tx_norm=None, max_steps=100, lr_max=10000, d0=0, pos_reg=1, lr_reduce=0.8, verbose=True, convergence_limit=0.01, max_step_limit=0.25, grad_limit_quantile=0.9, fixed_pos=0, minimize_only=False, data_fmod=0)[source]

Minimum entropy autofocus using backpropagation optimization through image formation.

Parameters:
  • f (function) – Radar image generation function.

  • data (Tensor) – Radar data.

  • data_time (Tensor) – Recording time of each data sample.

  • pos (Tensor) – Position at each data sample.

  • fc (float) – RF frequency in Hz.

  • r_res (float) – Range bin resolution in data (meters). For FMCW radar: c/(2*bw*oversample), where c is speed of light, bw is sweep bandwidth, and oversample is FFT oversampling factor.

  • grid (PolarGrid or dict) – Grid definition. Correct definition depends on the radar image function.

  • wa (Tensor) – Azimuth windowing function. Should be applied to data already, used for scaling gradient.

  • tx_norm (Tensor) – Radar image is divided by this tensor before calculating entropy. If None no division is done.

  • max_steps (int) – Maximum number of optimization steps.

  • lr_max (float) – Maximum learning rate. Too large learning rate is scaled automatically.

  • d0 (float) – Zero range correction.

  • pos_reg (float) – Position regularization value.

  • lr_reduce (float) – Learning rate is multiplied with this value if new entropy is larger than previously.

  • verbose (bool) – Print progress during optimization.

  • convergence_limit (float) – If maximum position change is below this value stop optimization. Units in wavelengths.

  • max_step_limit (float) – Maximum step size in wavelengths.

  • grad_limit_quantile (float) – Quantile used for maximum step size calculation. 0 to 1 range.

  • fixed_pos (int) – First fixed_pos positions are kept fixed and are not optimized.

  • minimize_only (bool) – Reject steps that would increase image entropy.

  • data_fmod (float) – Range modulation frequency applied to input data.

Returns:

  • sar_img (Tensor) – Optimized radar image.

  • origin (Tensor) – Mean of position tensor.

  • pos (Tensor) – Platform position.

  • step (int) – Number of steps.

Return type:

tuple[Tensor, Tensor, Tensor, int]

torchbp.autofocus.pga(img, window_width=None, max_iters=10, window_exp=0.5, min_window=5, remove_trend=True, offload=False, estimator='wls', eps=1e-06, spectrum_support=True, support_gate=0.01, max_targets=None, truncate=True, grid=None, fc=None, pos=None, att=None, g=None, g_extent=None, shifted=True, dem=None)[source]

Phase gradient autofocus

If an antenna pattern is given (g is not None), each selected target’s azimuth spectrum samples are additionally weighted by the modeled two-way antenna illumination. The spectrum bin to along-track pulse position mapping is the same far-field linear-track model as phase_to_pos() and the antenna model matches the gain lookup in the backprojection kernels.

In stripmap-like collections each target is illuminated only part of the full aperture. The global spectrum support gate only masks bins that no target occupies. For an individual target, bins outside its own illumination still enter its pair products and its “wls” amplitude statistics as clutter. The per-target antenna weight gates those samples out, exactly as the antenna-weighted gpga() path does in the pulse domain. In spotlight collections where every target is illuminated over the full aperture the weighting makes little difference.

Parameters:
  • img (Tensor) – Complex input image. Shape should be: [Range, azimuth].

  • window_width (int) – Initial window width. Default is None which measures the blur width from the image with pga_window_estimate(). Set explicitly to override, e.g. to the image size for the previous unwindowed first-iteration behavior.

  • max_iter (int) – Maximum number of iterations.

  • window_exp (float) – Exponent for decreasing the window size for each iteration.

  • min_window (int) – Minimum window size.

  • remove_trend (bool) – Remove linear trend that shifts the image.

  • offload (bool) – Offload some variable to CPU to save VRAM on GPU at the expense of longer running time.

  • estimator (str) – Estimator to use. See pga_estimator function for possible choices.

  • eps (float) – Minimum weight for weighted PGA.

  • spectrum_support (bool) – Restrict the estimate to azimuth spectrum bins that have signal. If the azimuth axis is oversampled (e.g. a cfbp image resampled with cart_to_polar), part of the spectrum is noise only. Without gating, the noise bins corrupt the estimator statistics and bias the trend removal, which shifts the image. The support is measured from the mean azimuth power spectrum, the phase estimate is integrated along the occupied band and the trend fit is weighted by the spectrum power.

  • support_gate (float) – Azimuth spectrum bins with mean power below this fraction of the maximum are considered unoccupied.

  • max_targets (int or None) – Estimate the phase error only from this many range rows with the highest peak-to-mean amplitude ratio. None (default) uses every row. Rows without a strong target get a near-zero weight from the “wls” estimator but still cost a windowed FFT and estimator pass, so on large images a few hundred rows gives nearly the same estimate much faster.

  • truncate (bool) – When the window is much smaller than the image, estimate the phase error from a zero-padded FFT of only the windowed samples instead of a full-length FFT and interpolate the estimate back onto the full azimuth spectrum. The windowed signal supports only about window independent estimate values, so a 4x oversampled short FFT loses almost nothing. Only affects speed; disable to reproduce the exact full-length estimates.

  • grid (PolarGrid or dict or None) – Polar grid definition of the image. Required for antenna weighting.

  • fc (float or None) – RF center frequency in Hz. Required for antenna weighting.

  • pos (Tensor or None) – Platform positions the image was formed with. Shape: [npulses, 3]. The track is assumed near-linear along the y axis. Required for antenna weighting.

  • att (Tensor or None) – Antenna rotation [roll, pitch, yaw] per pulse. Shape: [npulses, 3]. Required for antenna weighting.

  • g (Tensor or None) – Square-root of two-way antenna gain in spherical coordinates, shape: [elevation, azimuth]. If TX antenna equals RX antenna, then this should be just antenna gain. None (default) disables the antenna weighting.

  • g_extent (list or None) – Antenna gain extent in radians: [el0, az0, el1, az1]. Required for antenna weighting.

  • shifted (bool) – True if torchbp.util.shift_spectrum() was applied to the image (azimuth spectrum DC at bin ntheta // 2). False for an image straight from backprojection (DC at bin 0). Only used by the antenna weighting, where the spectrum layout matters: a wrong value mirrors the illumination weights. Without an antenna pattern pga is indifferent to the layout.

  • dem (Tensor or None) – Optional DEM sharing the grid extent for the antenna weighting target heights, otherwise targets are assumed at z = 0.

  • max_iters (int)

Returns:

  • img (Tensor) – Focused image.

  • phi (Tensor) – Solved phase error. Only meaningful over the occupied azimuth spectrum bins.

Return type:

tuple[Tensor, Tensor]

torchbp.autofocus.pga_estimator(g, estimator='wls', eps=1e-06, return_weight=False, weight=None, weight_gate=0.2, weight_norm=None, weight_pair=None)[source]

Estimate phase error from set of measurements.

Parameters:
  • g (Tensor) – Demodulated phase from each target. Shape [Ntargets, Nazimuth].

  • estimator (str) –

    Estimator to use.
    • ”pd”: Phase difference. [1]

    • ”ml”: Maximum likelihood. [2]

    • ”wls”: Weighted least squares using estimated signal-to-clutter weighting. [3]

  • eps (float) – Minimum weight for weighted PGA.

  • weight (Tensor or None) – Optional non-negative per-sample weight, shape [Ntargets, Nazimuth], e.g. the two-way antenna amplitude toward each target at each measurement. Weights are normalized per target. Samples with zero weight (target outside the antenna beam) do not contribute to the phase estimate; measurements where no target has weight get zero phase gradient. With “wls” the signal-to-clutter weights are estimated from the antenna-envelope-flattened amplitudes of the in-beam samples only. With “ml” the samples are gated by the weight before the SVD.

  • weight_gate (float) – Relative weight (to each target’s maximum) below which a sample is considered out of beam for the “wls” amplitude statistics and the “ml” gating.

  • weight_norm (Tensor or None) – Optional precomputed weight / max(weight, dim=1); skips the per-call normalization when the same weights are reused over many calls. Must match weight.

  • weight_pair (Tensor or None) – Optional precomputed weight_norm * shift(weight_norm) pair product (wn * pad(wn[..., :-1], (1, 0))), same reuse purpose. Must match weight.

  • return_weight (bool)

Return type:

Tuple[Tensor, Tensor] | Tensor

References

[1]

D. E. Wahl, P. H. Eichel, D. C. Ghiglia and C. V. Jakowatz, “Phase gradient autofocus - A robust tool for high resolution SAR phase correction,” in IEEE Transactions on Aerospace and Electronic Systems, vol. 30, no. 3, pp. 827-835, July 1994.

[2]

Charles V. Jakowatz and Daniel E. Wahl, “Eigenvector method for maximum-likelihood estimation of phase errors in synthetic-aperture-radar imagery,” J. Opt. Soc. Am. A 10, 2539-2546 (1993).

[3]

Wei Ye, Tat Soon Yeo and Zheng Bao, “Weighted least-squares estimation of phase errors for SAR/ISAR autofocus,” in IEEE Transactions on Geoscience and Remote Sensing, vol. 37, no. 5, pp. 2487-2494, Sept. 1999.

Returns:

phi – Solved phase error.

Return type:

Tensor

Parameters:
  • g (Tensor)

  • estimator (str)

  • eps (float)

  • return_weight (bool)

  • weight (Tensor | None)

  • weight_gate (float)

  • weight_norm (Tensor | None)

  • weight_pair (Tensor | None)

torchbp.autofocus.pga_window_estimate(img, thr_db=10.0, margin=2.0, min_window=8)[source]

Estimate the phase gradient autofocus window width from the image.

Measures the width of the average defocus kernel from the noncoherent sum of the peak-centered image rows [1]: with each row circularly shifted so its strongest pixel is at bin 0, the phase of the blur cancels in the intensity sum but its width survives, riding on a flat clutter pedestal. Rows are weighted by a signal-to-clutter proxy (peak-to-mean ratio squared) so target-free rows do not dilute the kernel, the pedestal is estimated as the median of the summed profile, and the width is measured at thr_db below the pedestal-subtracted peak.

A sinusoidal phase error produces discrete paired echoes rather than a continuous blur, and the dips between echoes would end the width measurement early. The profile is therefore smoothed with a window scaled to the current width estimate and re-measured until the estimate is stable, so the smoothing bridges the echo spacing whatever it is.

On a well focused image the estimate collapses to the target mainlobe width, so it can also be used as a convergence indicator.

References

[1]

D. E. Wahl, P. H. Eichel, D. C. Ghiglia and C. V. Jakowatz, “Phase gradient autofocus - A robust tool for high resolution SAR phase correction,” in IEEE Transactions on Aerospace and Electronic Systems, vol. 30, no. 3, pp. 827-835, July 1994.

Parameters:
  • img (Tensor) – Complex input image. Shape should be: [Range, azimuth].

  • thr_db (float) – Width is measured where the pedestal-subtracted kernel profile drops this many dB below its peak.

  • margin (float) – Safety factor applied to the measured width.

  • min_window (int) – Lower bound of the returned window width.

Returns:

window_width – Estimated window width in azimuth bins, at most the azimuth size.

Return type:

int

torchbp.autofocus.pga_xz(img, grid, fc, h, range_divisions=4, window_width=None, max_iters=10, window_exp=0.5, min_window=5, remove_trend=True, estimate_z=True, solve_threshold=0.003, eps=1e-06, spectrum_support=True, support_gate=0.01, truncate=True, pos=None, att=None, g=None, g_extent=None, dem=None)[source]

Phase gradient autofocus with range-direction and vertical (x, z) position error estimation.

Image-domain variant of gpga_tde() restricted to the range-direction (x) and vertical (z) platform position error components. For these two components the phase error of a pixel depends on the pixel direction only through the elevation angle, which on a polar grid is a function of the range row alone (scene assumed at z = 0), so the error decomposes over the image: at range row r and azimuth spectrum bin k

phi(k, r) = (4 pi fc / c) * (cos(az_c) * cos(el(r)) * dx(k) + sin(el(r)) * dz(k))

where az_c is the grid center azimuth. The profiles dx and dz are estimated by running the PGA estimator on blocks of range rows and solving the two components per spectrum bin from the block phases, and the correction is applied with per-row multiplies in the azimuth spectrum domain. Unlike gpga() / gpga_tde() no raw data is needed and no image re-formation is done; the whole algorithm runs on the image with FFTs.

The azimuth spectral variable of a target scales with cos(el): the same along-track platform offset lands on different spectrum bins at different range rows. Block estimates are resampled onto a common spectral axis referenced to the row with the largest cos(el) before the per-bin solve, and the correction is resampled back per row.

The along-track (y) error component is not modeled: its phase error is proportional to the theta coordinate within the image, which does not decompose over range rows. At broadside it is also the component that defocuses least.

If an antenna pattern is given (g is not None), each range row’s azimuth spectrum samples are weighted by the modeled two-way antenna illumination toward its strongest target, as in the antenna-weighted pga(). This gates out the out-of-beam clutter bins in stripmap-like collections where each target is illuminated only part of the aperture. pga_xz expects an image straight from backprojection (no torchbp.util.shift_spectrum()), so unlike in pga() there is no shifted option. Note that in this regime the block-wise estimation needs several illuminated targets per range block: each gated target constrains the phase only over its own spectrum sub-band, and where a block’s targets leave coverage gaps the integrated block phase picks up offsets that corrupt the per-bin solve. With too few targets per block the antenna-weighted pga() is the more robust choice.

Parameters:
  • img (Tensor) – Complex input image on a polar grid. Shape: [range, azimuth].

  • grid (PolarGrid or dict) – Polar grid definition of the image.

  • fc (float) – RF center frequency in Hz.

  • h (float) – Mean platform altitude above the scene plane in meters (e.g. torch.mean(pos[:, 2])).

  • range_divisions (int) – Number of range blocks the phase error is estimated from. Must be at least 2 when estimate_z is True. More blocks improve the conditioning of the x/z separation at the cost of fewer rows per block estimate.

  • window_width (int) – Initial window width. Default is None which measures the blur width from the image with pga_window_estimate(). Avoid an unwindowed (image sized) estimate on a large image: it is dominated by phase-difference random-walk noise, which the x/z solve amplifies (an unwindowed first pass therefore solves the range-direction component only), and it is also the expensive iteration the truncated estimation cannot shorten.

  • max_iters (int) – Maximum number of iterations.

  • window_exp (float) – Exponent for decreasing the window size for each iteration.

  • min_window (int) – Minimum window size.

  • remove_trend (bool) – Remove linear trend of the solved profiles that only shifts the image.

  • estimate_z (bool) – Estimate the vertical error component. Requires elevation angle variation over the range swath. Automatically disabled when h == 0.

  • solve_threshold (float) – Relative eigenvalue threshold of the per-bin (x, z) solve. If the elevation angle spread over the range swath is too small to separate z from x, the weakly observed direction gets zero update instead of amplified noise.

  • eps (float) – Minimum weight for weighted PGA.

  • spectrum_support (bool) – Restrict the estimate to azimuth spectrum bins that have signal. See pga().

  • support_gate (float) – Azimuth spectrum bins with mean power below this fraction of the maximum are considered unoccupied.

  • truncate (bool) – When the window is much smaller than the image, estimate the block phases from a zero-padded FFT of only the windowed samples instead of a full-length FFT, as in pga(). The short-grid estimate is interpolated onto the common spectral axis by the same resampling step that handles the per-block cos(el) scaling. Only affects speed; disable to reproduce the exact full-length estimates.

  • pos (Tensor or None) – Platform positions the image was formed with. Shape: [npulses, 3]. The track is assumed near-linear along the y axis. Required for antenna weighting.

  • att (Tensor or None) – Antenna rotation [roll, pitch, yaw] per pulse. Shape: [npulses, 3]. Required for antenna weighting.

  • g (Tensor or None) – Square-root of two-way antenna gain in spherical coordinates, shape: [elevation, azimuth]. If TX antenna equals RX antenna, then this should be just antenna gain. None (default) disables the antenna weighting.

  • g_extent (list or None) – Antenna gain extent in radians: [el0, az0, el1, az1]. Required for antenna weighting.

  • dem (Tensor or None) – Optional DEM sharing the grid extent for the antenna weighting target heights, otherwise targets are assumed at z = 0.

Returns:

  • img (Tensor) – Focused image.

  • d (Tensor) – Solved position error profiles in meters, shape [2, ntheta]. d[0] is the range-direction (x) and d[1] the vertical (z) error as a function of fftshifted azimuth spectrum bin on the common spectral axis (bin ntheta // 2 is zero azimuth frequency, the bin is proportional to along-track position with unknown scale and sign). Only meaningful over the occupied spectrum bins. With remove_trend the unobservable linear trends are removed.

Return type:

tuple[Tensor, Tensor]

torchbp.autofocus.phase_to_pos(phi, grid, fc, pos, shifted=True)[source]

Convert a phase error profile solved by pga() to a range-direction (x) platform position error at each pulse.

A range-direction platform position error dx at a pulse creates a phase error phi = (4 pi fc / c) * cos(az_c) * cos(el) * dx on the azimuth spectrum bin that the pulse maps to, where az_c is the grid center azimuth and el the elevation angle to the grid center (scene assumed at z = 0). The azimuth spectrum bin of a pulse is proportional to its along-track (y) coordinate, so the solved phase is scaled to meters and interpolated at the actual y coordinate of each pulse. Using the per-pulse coordinates instead of assuming a uniform mapping supports non-uniformly sampled and slightly non-linear tracks.

The mean and linear trend of the phase error are unobservable to pga() (they only shift the image) and are removed by its remove_trend, so the returned profile is comparable to the true position error only up to a linear function of the along-track coordinate.

Parameters:
  • phi (Tensor) – Solved phase error from pga() in radians. Shape: [ntheta].

  • grid (PolarGrid or dict) – Polar grid definition of the image the phase was solved from.

  • fc (float) – RF center frequency in Hz.

  • pos (Tensor) – Platform positions the image was formed with. Shape: [npulses, 3].

  • shifted (bool) – True if torchbp.util.shift_spectrum() was applied to the image before pga() (azimuth spectrum DC at bin ntheta // 2). False for an image straight from backprojection (DC at bin 0).

Returns:

dx – Estimated range-direction (x) position error in meters at each pulse, shape [npulses]. This is the true minus the nominal position: adding it to pos[:, 0] and re-forming the image corrects the error.

Return type:

Tensor