Antennas
Reference for AntennaState, ReceiverGrid, AntennaPattern and antenna_orientation_matrix - transmitter and receiver endpoints in a Core scene.
The antenna classes live in witwin.core.antenna and are exported from witwin.core. For examples, see Place antennas and receiver grids.
from witwin.core import AntennaPattern, AntennaState, ReceiverGrid, antenna_orientation_matrixVector fields accept a sequence (converted to a float32 tensor) or a tensor (stored as is). All tensor fields of one endpoint must be on one device, otherwise ValueError.
AntennaState#
class AntennaState(
antenna_id: AntennaId | int,
role: Literal["tx", "rx"],
position,
*,
orientation=None,
polarization=None,
element_positions=None,
weights=None,
synthetic_array: bool = True,
pattern: AntennaPattern | str = "isotropic",
power_w: ScalarLike | None = None,
metadata: Mapping[str, Any] | None = None,
)A solver-neutral transmitter or receiver. Immutable (frozen dataclass).
The endpoint's ID, reserved so that automatic IDs skip it. Must be at least 0. Unique within a scene.
Transmitter or receiver. Other values raise ValueError.
World position in metres. Must be floating point.
NoneLocal-to-world rotation. (3,) is Euler (yaw, pitch, roll) in radians, intrinsic Z-Y-X; (4,) is a unit quaternion (w, x, y, z). None is the identity. Other shapes raise ValueError.
NonePolarization vector in the local frame.
NoneArray element positions in the local frame, in metres.
NonePer-element weights, real or complex. Must have one value per element when element_positions is set.
TrueA flag for solvers that controls how they model an array. See the solver's documentation.
'isotropic'A pattern kind string or an AntennaPattern. Other types raise TypeError.
NoneTransmit power in watts. A tensor must be 0-d and floating point.
NoneFree-form data, stored as a read-only mapping.
All arguments are attributes with the same names.
AntennaState.orientation_matrix#
orientation_matrix() -> torch.TensorReturns the (3, 3) local-to-world rotation, computed from orientation in its dtype. Without an orientation it returns the identity on the device and in the dtype of position. Keeps autograd.
AntennaState.polarization_world#
polarization_world() -> torch.Tensor | NoneReturns orientation_matrix() @ polarization (world frame), or None without a polarization. Keeps autograd.
ReceiverGrid#
class ReceiverGrid(
antenna_id: AntennaId | int,
origin,
x_axis,
y_axis,
shape,
spacing,
*,
orientation=None,
polarization=None,
element_positions=None,
weights=None,
synthetic_array: bool = True,
pattern: AntennaPattern | str = "isotropic",
metadata: Mapping[str, Any] | None = None,
)A row-major planar grid of receiver samples that counts as one "rx" endpoint with one ID. Subclass of AntennaState.
The grid's endpoint ID.
World position of sample (0, 0). Stored as position.
World direction of increasing row index. Not normalised.
World direction of increasing column index. Not normalised.
(rows, columns), both positive integers.
(row spacing, column spacing) in metres. Python values must be positive.
The keyword-only arguments are as for AntennaState. The role is always "rx" and there is no power_w.
| Member | Description |
|---|---|
origin | Property: the same tensor as position. |
x_axis, y_axis, spacing | The tensors given (or converted on the device and dtype of origin). |
shape | (rows, columns) as a tuple of int. |
points() | (rows * columns, 3) world positions: sample (r, c) is origin + r * spacing[0] * x_axis + c * spacing[1] * y_axis, row-major. Keeps autograd. |
AntennaPattern#
@dataclass(frozen=True, slots=True)
class AntennaPattern:
kind: str = "isotropic"
custom: Callable[[torch.Tensor], torch.Tensor] | None = NoneThe pattern identity of an endpoint. kind is "isotropic", "vertical", "horizontal" or "custom". custom must be a callable exactly when kind == "custom". Otherwise ValueError. Core never calls custom; the solver defines its argument.
antenna_orientation_matrix#
antenna_orientation_matrix(orientation: torch.Tensor | None, *, reference: torch.Tensor) -> torch.TensorReturns the (3, 3) local-to-world rotation for an antenna orientation.
Euler (yaw, pitch, roll) or quaternion (w, x, y, z).
A tensor whose device and dtype the identity matrix takes when orientation is None.
import math
import torch
from witwin.core import antenna_orientation_matrix
R = antenna_orientation_matrix(torch.tensor([math.pi / 2, 0.0, 0.0]), reference=torch.zeros(3))
print((R @ torch.tensor([1.0, 0.0, 0.0])).round(decimals=3))tensor([-0., 1., 0.])