Range and Doppler processing

ProcessingCube, RangeProfile and RangeDopplerMap, and the range_profile and range_doppler_map functions that turn a cube into range and velocity.

This page covers the range and Doppler stage of witwin.radar.processing. Frame.range_profile() and Frame.range_doppler() call these functions for you. Call them directly when you need the typed records in your own pipeline.

from witwin.radar.processing import ProcessingCube, RangeDopplerMap, RangeProfile, range_doppler_map, range_profile

Two conventions hold for every waveform:

  • Amplitude. Each transform is amplitude normalized, so an isolated row on a bin peaks at abs(C) · window_coherent_gain, where C is its transfer coefficient and window_coherent_gain is the mean of the window.
  • Doppler sign. A positive Doppler bin is a closing target. range_doppler_map is the only place the sign is reconciled with the cube's phasor.

Windows are named: "rectangular" (all ones), "hann", "hamming" and "blackman". None means rectangular.

ProcessingCube#

class ProcessingCube(data, axes)

A complex [TX, RX, slow, fast] tensor with the ProcessingAxes that describe it. Bare tensors are refused by range_profile, because the fast axis alone cannot tell an FMCW spectrum from a beat signal.

Field or propertyMeaning
dataComplex tensor [TX, RX, C, S], with C slow-time and S fast-time samples.
axesProcessingAxes. See Results.
deviceDevice of data.

Get one with frame.processing_cube().

range_profile#

range_profile(cube, *, window=None, remove_dc=False) -> RangeProfile

Transform the fast axis to range. The method depends on cube.axes.waveform:

  • FMCW: an FFT over fast time. For output="spectrum" the cube is already range-transformed, so only the rectangular window is accepted.
  • OFDM: an inverse FFT over subcarriers, which gives the channel impulse response.
  • Pulsed: a matched filter that correlates the train against the analytic pulse replica.
cubeProcessingCuberequired

The cube and its axes. Leading batch dimensions are allowed.

windowstr | Nonedefault None

Window applied to the input of the final transform. None is rectangular.

remove_dcbooldefault False

Subtract the fast-time mean first. On an FMCW spectrum cube, which is already transformed, it zeroes the first range bin instead. A clutter operation, so it is off by default.

Returns RangeProfile.

Raises TypeError for a bare tensor. ValueError for a fast-time window on an FMCW spectrum cube or an unknown window name.

profile = range_profile(frame.processing_cube())
print(profile.data.shape, profile.range_axis[:3])

RangeProfile#

class RangeProfile(data, axes, window, window_coherent_gain)

Complex [..., C, R]: one range profile per slow-time sample.

Field or propertyMeaning
dataComplex tensor [..., C, R].
axesProcessingAxes.
windowName of the window used.
window_coherent_gainMean of the window. For pulsed cubes with a window it is a spectrum-weighted mean, and the amplitude identity holds only without a window.
range_axis[R] float64 range, m.

range_doppler_map#

range_doppler_map(profile, *, window=None) -> RangeDopplerMap

Transform the slow axis to Doppler. The output is fftshifted and in the closing-positive convention for every waveform. The transform carries a 1 / D factor, so the coherent integration gain is not in the amplitude.

profileRangeProfilerequired

The range profile. Leading batch dimensions are allowed, such as [TX, RX, C, R] or [P, C, R].

windowstr | Nonedefault None

Slow-time window. None is rectangular. Frame.range_doppler() uses "hann".

Returns RangeDopplerMap.

rd = range_doppler_map(range_profile(frame.processing_cube()), window="hann")
power = rd.data.abs().square().sum(dim=(0, 1))       # [doppler, range]
d, r = divmod(int(power.argmax()), power.shape[1])
print(float(rd.doppler_axis[d]), float(rd.range_axis[r]))

RangeDopplerMap#

class RangeDopplerMap(data, axes, window, window_coherent_gain)

Complex [..., D, R].

Field or propertyMeaning
dataComplex tensor [..., D, R].
axesProcessingAxes.
windowName of the slow-time window.
window_coherent_gainMean of the slow-time window.
range_axis[R] float64 range, m.
doppler_axis[D] float64 radial velocity, m/s, ascending, positive for a closing target.

Both functions are differentiable; see Differentiability.