Antenna pattern

The Pattern record for element power gain, with the isotropic, dipole, separable and table constructors and the angle convention they use.

Pattern is a tabulated element power gain against two off-boresight angles. Radar(pattern=...) applies it to every transmit and receive leg of every round trip.

from witwin.radar import Pattern

Build a pattern with one of the four class methods below, not by naming the fields. See Use antenna patterns for worked examples.

Angle convention#

For a direction v in the radar's local frame (boresight -z):

  • x = atan2(v_x, -v_z), in degrees.
  • y = atan2(v_y, -v_z), in degrees.

Gains are linear power gains, normalized to at most 1. Between samples the gain is interpolated linearly. Outside the tabulated angles the gain is exactly zero, so a pattern that spans -90° to 90° does not radiate behind the radar. The table itself is a constant, but the gain is differentiable with respect to the direction.

Pattern.isotropic#

Pattern.isotropic() -> Pattern

Unit gain in every direction. Both axes span -180° to 180°. This is the default of Radar.pattern.

Pattern.dipole#

Pattern.dipole() -> Pattern

A half-wave dipole cut in both planes, sampled from -90° to 90° in 1° steps. A separable pattern.

radar = radar.replace(pattern=Pattern.dipole())

Pattern.separable#

Pattern.separable(x_angles, x_gain, y_angles, y_gain) -> Pattern

A pattern whose gain is the product of an x cut and a y cut: G(x, y) = x_gain(x) · y_gain(y).

x_anglessequence of floatrequired

x angles, degrees, strictly increasing, at least two.

x_gainsequence of floatrequired

Non-negative power gain at each x angle.

y_anglessequence of floatrequired

y angles, degrees, strictly increasing, at least two.

y_gainsequence of floatrequired

Non-negative power gain at each y angle.

Returns Pattern with kind == "separable".

Raises ValueError if an axis has fewer than two samples, is not strictly increasing, has a gain list of a different length, or holds a negative gain.

pattern = Pattern.separable(
    x_angles=[-60, -30, 0, 30, 60], x_gain=[0.1, 0.6, 1.0, 0.6, 0.1],
    y_angles=[-40, 0, 40], y_gain=[0.3, 1.0, 0.3],
)

Pattern.table#

Pattern.table(x_angles, y_angles, gain) -> Pattern

A pattern tabulated on the full grid, for a measured pattern that is not separable.

x_anglessequence of floatrequired

x angles, degrees, strictly increasing, at least two.

y_anglessequence of floatrequired

y angles, degrees, strictly increasing, at least two.

gainsequence of sequences of floatrequired

Non-negative power gain as gain[y][x]: one row per y angle, one entry per x angle in each row.

Returns Pattern with kind == "map".

Raises ValueError if an axis has fewer than two samples or is not strictly increasing, gain does not have one row per y angle and one entry per x angle, or a gain is negative.

pattern = Pattern.table(
    x_angles=[-45, 0, 45],
    y_angles=[-30, 30],
    gain=[[0.2, 0.7, 0.2],    # y = -30
          [0.3, 1.0, 0.3]],   # y = 30
)

Fields#

FieldTypeMeaning
kindstr"separable" or "map".
x_anglestuple[float, ...]x axis, degrees.
y_anglestuple[float, ...]y axis, degrees.
x_gain, y_gaintuple[float, ...] or NoneThe two cuts of a separable pattern.
gaintuple[tuple[float, ...], ...] or NoneThe gain[y][x] grid of a table pattern.

In a configuration file, the same patterns are written under antenna_pattern. See Load a radar configuration file.