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.
| Field | Meaning |
|---|---|
num_samples, num_chirps | ADC samples per chirp and chirps per frame. |
sample_period_s, chirp_period_s | ADC sample period and chirp period, s. |
slope_hz_per_s | Chirp slope, Hz/s. |
t_start_s | ADC start time within the chirp, s. |
reference_frequency_hz | Carrier, Hz. |
carrier_hz, carrier_rate_hz | The two carrier homes. Default 0.0. |
num_tx, num_rx | TDM-MIMO array size. Default 1. |
output_domain | "spectrum" or "beat". |
| Property or method | Returns |
|---|---|
sample_rate_hz | 1 / sample_period_s, Hz. |
sensor_pair_count | num_tx · num_rx. |
wavelength_m | Carrier wavelength, m. |
slot_period_s | chirp_period_s · num_tx, the period between two chirps of the same transmitter, s. |
max_unambiguous_speed_mps | wavelength / (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.
| Field | Meaning |
|---|---|
num_subcarriers, num_symbols | Grid size. |
subcarrier_spacing_hz | Subcarrier spacing, Hz. |
cyclic_prefix_s | Cyclic prefix, s. |
reference_frequency_hz | Carrier, Hz. Subcarrier 0 sits here. |
max_expected_delay_s | Configured delay bound, s. Must be below cyclic_prefix_s. |
carrier_hz, carrier_rate_hz | The two carrier homes. |
subcarrier_origin | "f_ref_at_n0". |
| Property or method | Returns |
|---|---|
useful_symbol_time_s | 1 / subcarrier_spacing_hz, s. |
symbol_period_s | useful_symbol_time_s + cyclic_prefix_s, the slow-time period, s. |
waveform_sample_period_s, delay_resolution_s | 1 / (num_subcarriers · subcarrier_spacing_hz), s. |
occupied_bandwidth_hz | num_subcarriers · subcarrier_spacing_hz, Hz. |
range_resolution_m | c0 / (2 · occupied_bandwidth_hz), m. |
max_unambiguous_delay_s | 1 / subcarrier_spacing_hz, s. |
wavelength_m | Carrier wavelength, m. |
max_unambiguous_speed_mps | wavelength / (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.
| Field | Meaning |
|---|---|
num_pulses, num_samples | Pulses per frame and samples per range gate. |
sample_period_s, pri_s | Sample period and pulse repetition interval, s. |
range_gate_start_s | Range gate opening delay, s. |
pulse_kind | "rect" or "lfm". |
pulse_width_s, bandwidth_hz | Pulse duration, s, and bandwidth, Hz. |
reference_frequency_hz | Carrier, Hz. |
max_expected_delay_rate | Configured delay-rate bound, s/s. |
carrier_hz, carrier_rate_hz | The two carrier homes. |
pulse_normalization | "unit_energy". |
| Property or method | Returns |
|---|---|
sample_rate_hz, wavelength_m, is_linear_fm | As named. |
pulse_amplitude | 1 / sqrt(pulse_width_s). |
pulse_sample_count | round(pulse_width_s / sample_period_s). |
pulse_grid_is_commensurate | Whether the pulse is a whole number of samples. |
range_gate_end_s | range_gate_start_s + num_samples · sample_period_s, s. |
duty_cycle | pulse_width_s / pri_s. |
range_resolution_m | c0 / (2 · bandwidth_hz) for LFM, c0 · pulse_width_s / 2 for rect, m. |
max_unambiguous_range_m | c0 · pri_s / 2, m. |
max_unambiguous_speed_m_s | wavelength / (4 · pri_s), m/s. |
coherent_processing_interval_s | num_pulses · pri_s, s. |
range_cell_delay_s | 1 / bandwidth_hz, s. |
range_migration_delay_s | max_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.
| Field | Meaning |
|---|---|
cube | Complex cube [slow, pair, fast]. |
kind | Waveform kind. |
axes | Axis names. |
phasor, time_dependence | Phase and time conventions. |
reference_frequency_hz | Carrier, 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:
| Value | Meaning |
|---|---|
SlowTimeMode.FROZEN_WEIGHT_WITH_CARRIER_RATE | One weight per frame; the carrier rate term supplies the slow-time phase. |
SlowTimeMode.REFRESHED_WEIGHT_NO_RATE | Weights 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) -> SynthesisPathBatchThe 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.