Scattering

The ScatterResponse protocol and the ScalarRcsResponse and AspectScatterResponse records that witwin.radar builds from PointTargets.

witwin.radar.scattering holds the target responses that join an inbound and an outbound leg at a scatter site. PointTargets and StructureTargets build them for you: a scalar rcs or amplitude gives a ScalarRcsResponse, and an Aspect gives an AspectScatterResponse. Use this module directly only to build or inspect a response yourself.

from witwin.radar.scattering import AspectScatterResponse, ScalarRcsResponse, ScatterResponse

Every response is written in Channel's phasor convention, exp(-j·k·d), because it multiplies Channel's transfer coefficients.

The cross section and the dimensionless strength are related by

amplitude = sqrt(4 * pi * sigma) / wavelength

Leaving out the 4 · pi / wavelength^2 factor is 58 dB wrong at 77 GHz, so build from a cross section with ScalarRcsResponse.from_rcs.

ScatterResponse#

class ScatterResponse(Protocol)

The protocol every response satisfies.

MemberMeaning
evaluate(row_count, device)complex64[row_count], one value per composed row.
is_geometry_dependentTrue if the value depends on each row's geometry rather than only on the target. Such a response must be evaluated in a native kernel.

ScalarRcsResponse#

class ScalarRcsResponse(amplitude, phase_rad)

Isotropic response S = amplitude · exp(-j · phase_rad). Both fields are 0-dim tensors, and both may carry a gradient.

ScalarRcsResponse.from_rcs#

ScalarRcsResponse.from_rcs(sigma_m2, *, reference_frequency_hz, phase_rad=0.0, device='cpu', requires_grad=False) -> ScalarRcsResponse

Build from a radar cross section.

sigma_m2float | 0-dim tensorrequired

Radar cross section, m². A 0-dim tensor becomes the gradient leaf.

reference_frequency_hzfloatrequired

Carrier, Hz. Sets the wavelength in the law above.

phase_radfloatdefault 0.0

Scattering phase, rad.

devicestr | torch.devicedefault 'cpu'

Device for a response built from a Python float. A tensor cross section keeps its own device.

requires_gradbooldefault False

Mark the amplitude as a leaf. Refused with a tensor sigma_m2, which is already the leaf.

response = ScalarRcsResponse.from_rcs(1.0, reference_frequency_hz=77e9, device="cuda")
print(response.amplitude)

ScalarRcsResponse.from_values#

ScalarRcsResponse.from_values(amplitude, phase_rad, *, device='cpu', requires_grad=False) -> ScalarRcsResponse

Build from the dimensionless strength directly.

AspectScatterResponse#

class AspectScatterResponse(axis, amplitude, phase_rad, exponent, coherent_interval_s, aspect_phase_rate_rad_per_s=0.0)

A separable two-way lobe with one parameter set per scatter site. The value of each row depends on its inbound and outbound directions, so it is evaluated per row in a native kernel. evaluate is refused; the composer calls evaluate_rows instead.

FieldMeaning
axis[S, 3] unit vectors of strongest return. May carry a gradient. Checked for unit length once at construction.
amplitude[S] strength. May carry a gradient.
phase_rad[S] phase, rad. May carry a gradient.
exponentLobe sharpness, at least 1.
coherent_interval_sHow long one aspect realization stays coherent, s.
aspect_phase_rate_rad_per_sDeclared aspect phase drift, rad/s.
site_countS.

AspectScatterResponse.from_values(axis, amplitude, phase_rad, *, exponent, coherent_interval_s, aspect_phase_rate_rad_per_s=0.0, device='cuda', requires_grad=False) builds one from host sequences, one row per site. PointTargets(aspect=Aspect(...)) is the usual route; see Targets.