Synthesis

The SI waveform specs FmcwSpec, OfdmSpec and PulsedSpec, SynthesisResult, SynthesisPathBatch and the component selector in witwin.radar.synthesis.

witwin.radar.synthesis holds the SI waveform specs and the records the synthesis kernels exchange. Most code never imports it: Radar.echo is the entry point to synthesis, and the public synthesis functions were removed in 0.4.0. Read this page when you need a spec's derived quantities or the conventions of a cube.

from witwin.radar.synthesis import (FmcwSpec, OfdmSpec, PulsedSpec, SlowTimeMode, SynthesisPathBatch,
                                    SynthesisResult, select_component)

Get the spec of a radar with radar.waveform_spec(). Every spec is a frozen dataclass in SI units.

The carrier phase has two homes, and exactly one of carrier_hz and carrier_rate_hz is nonzero. Radar's own route sets carrier_rate_hz to the carrier, because Channel's transfer coefficient already holds the absolute carrier phase; the kernel then applies the carrier to the change in delay only. Setting both is refused.

FmcwSpec#

One chirp frame's sampling grid and ramp.

FieldMeaning
num_samples, num_chirpsADC samples per chirp and chirps per frame.
sample_period_s, chirp_period_sADC sample period and chirp period, s.
slope_hz_per_sChirp slope, Hz/s.
t_start_sADC start time within the chirp, s.
reference_frequency_hzCarrier, Hz.
carrier_hz, carrier_rate_hzThe two carrier homes. Default 0.0.
num_tx, num_rxTDM-MIMO array size. Default 1.
output_domain"spectrum" or "beat".
Property or methodReturns
sample_rate_hz1 / sample_period_s, Hz.
sensor_pair_countnum_tx · num_rx.
wavelength_mCarrier wavelength, m.
slot_period_schirp_period_s · num_tx, the period between two chirps of the same transmitter, s.
max_unambiguous_speed_mpswavelength / (4 · chirp_period_s · num_tx), m/s.
beat_frequency_hz(round_trip_delay_s)slope · delay, Hz. No factor of 2: the delay is already round trip.
beat_bin(round_trip_delay_s)Fractional FFT bin of the beat tone.

OfdmSpec#

One OFDM frame's subcarrier grid and symbol timing. The cube is the channel frequency response H[symbol, pair, subcarrier] in Channel's phasor convention.

FieldMeaning
num_subcarriers, num_symbolsGrid size.
subcarrier_spacing_hzSubcarrier spacing, Hz.
cyclic_prefix_sCyclic prefix, s.
reference_frequency_hzCarrier, Hz. Subcarrier 0 sits here.
max_expected_delay_sConfigured delay bound, s. Must be below cyclic_prefix_s.
carrier_hz, carrier_rate_hzThe two carrier homes.
subcarrier_origin"f_ref_at_n0".
Property or methodReturns
useful_symbol_time_s1 / subcarrier_spacing_hz, s.
symbol_period_suseful_symbol_time_s + cyclic_prefix_s, the slow-time period, s.
waveform_sample_period_s, delay_resolution_s1 / (num_subcarriers · subcarrier_spacing_hz), s.
occupied_bandwidth_hznum_subcarriers · subcarrier_spacing_hz, Hz.
range_resolution_mc0 / (2 · occupied_bandwidth_hz), m.
max_unambiguous_delay_s1 / subcarrier_spacing_hz, s.
wavelength_mCarrier wavelength, m.
max_unambiguous_speed_mpswavelength / (4 · symbol_period_s), m/s.
subcarrier_frequency_hz(subcarrier)f_ref + n · subcarrier_spacing_hz, Hz.
subcarrier_phase_step_rad(round_trip_delay_s)-2 · pi · subcarrier_spacing_hz · delay, rad.
cir_peak_sample(round_trip_delay_s)Fractional impulse-response sample of the echo.

OFDM synthesis is narrowband: material and antenna responses are frozen at the carrier across the band.

PulsedSpec#

One pulsed frame's range gate, pulse shape and PRI. The cube is the received baseband train y[pulse, pair, sample], the matched-filter input. The pulse is evaluated at the exact fractional delay, never snapped to a sample.

FieldMeaning
num_pulses, num_samplesPulses per frame and samples per range gate.
sample_period_s, pri_sSample period and pulse repetition interval, s.
range_gate_start_sRange gate opening delay, s.
pulse_kind"rect" or "lfm".
pulse_width_s, bandwidth_hzPulse duration, s, and bandwidth, Hz.
reference_frequency_hzCarrier, Hz.
max_expected_delay_rateConfigured delay-rate bound, s/s.
carrier_hz, carrier_rate_hzThe two carrier homes.
pulse_normalization"unit_energy".
Property or methodReturns
sample_rate_hz, wavelength_m, is_linear_fmAs named.
pulse_amplitude1 / sqrt(pulse_width_s).
pulse_sample_countround(pulse_width_s / sample_period_s).
pulse_grid_is_commensurateWhether the pulse is a whole number of samples.
range_gate_end_srange_gate_start_s + num_samples · sample_period_s, s.
duty_cyclepulse_width_s / pri_s.
range_resolution_mc0 / (2 · bandwidth_hz) for LFM, c0 · pulse_width_s / 2 for rect, m.
max_unambiguous_range_mc0 · pri_s / 2, m.
max_unambiguous_speed_m_swavelength / (4 · pri_s), m/s.
coherent_processing_interval_snum_pulses · pri_s, s.
range_cell_delay_s1 / bandwidth_hz, s.
range_migration_delay_smax_expected_delay_rate · num_pulses · pri_s, s. Must not exceed one range cell.
instantaneous_pulse_frequency_hz(envelope_time_s)LFM frequency offset at a point in the pulse, Hz. 0 for rect.
slow_time_phase_step_rad(delay_rate, envelope_time_s=0.0)Phase advance per pulse at a fixed sample, rad.
doppler_frequency_hz(delay_rate)-f_ref · delay_rate, Hz.
spec = radar.waveform_spec()
print(spec.max_unambiguous_speed_mps, spec.slot_period_s)

SynthesisResult#

class SynthesisResult(cube, kind, axes, phasor, time_dependence, reference_frequency_hz, output_domain)

One synthesized frame and its conventions. Result.frame_synthesis(index) returns one. SynthesisResult.from_fmcw(cube, spec), from_ofdm and from_pulsed build one from a cube and its spec.

FieldMeaning
cubeComplex cube [slow, pair, fast].
kindWaveform kind.
axesAxis names.
phasor, time_dependencePhase and time conventions.
reference_frequency_hzCarrier, Hz.
output_domain"spectrum", "beat", "cfr" or "time".

SynthesisPathBatch and SlowTimeMode#

SynthesisPathBatch wraps a RadarPathBatch for the synthesis kernels without copying it: per-row delays total_delay_s, delay rates delay_rate, transfer coefficients complex_transfer_ref, the pair partition sensor_pair_index and pair_offsets, row_valid, and provenance flags (weight_includes_reference_phase, weight_includes_spreading, weight_includes_tx_power, weight_includes_antenna_pattern). Build one with SynthesisPathBatch.from_radar_paths(paths, *, slow_time_mode).

SlowTimeMode says how the weights move across slow time:

ValueMeaning
SlowTimeMode.FROZEN_WEIGHT_WITH_CARRIER_RATEOne weight per frame; the carrier rate term supplies the slow-time phase.
SlowTimeMode.REFRESHED_WEIGHT_NO_RATEWeights refreshed per observation; no rate term.

slow_time_mode has no default, because the wrong choice double-counts or drops the Doppler phase.

select_component#

select_component(batch, index, name) -> SynthesisPathBatch

The same batch with every row outside component name made inert, so its contribution is exactly zero. index is a RadarComponentIndex built from the same batch's topology, checked by object identity.