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, ScatterResponseEvery 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) / wavelengthLeaving 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.
| Member | Meaning |
|---|---|
evaluate(row_count, device) | complex64[row_count], one value per composed row. |
is_geometry_dependent | True 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) -> ScalarRcsResponseBuild from a radar cross section.
Radar cross section, m². A 0-dim tensor becomes the gradient leaf.
Carrier, Hz. Sets the wavelength in the law above.
0.0Scattering phase, rad.
'cpu'Device for a response built from a Python float. A tensor cross section keeps its own device.
FalseMark 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) -> ScalarRcsResponseBuild 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.
| Field | Meaning |
|---|---|
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. |
exponent | Lobe sharpness, at least 1. |
coherent_interval_s | How long one aspect realization stays coherent, s. |
aspect_phase_rate_rad_per_s | Declared aspect phase drift, rad/s. |
site_count | S. |
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.