Geometry Module#

The geometry module provides classes and functions for creating various array geometries, from simple rectangular grids to complex conformal and sparse arrays.

Classes#

class phased_array.ArrayGeometry(x, y, z=None, nx=None, ny=None, nz=None, element_indices=None)[source]#

Bases: object

Container for phased array element positions and orientations.

x#

Element x-positions in meters

Type:

ndarray

y#

Element y-positions in meters

Type:

ndarray

z#

Element z-positions in meters (for 3D/conformal arrays)

Type:

ndarray, optional

nx#

Element normal x-components (unit vectors)

Type:

ndarray, optional

ny#

Element normal y-components

Type:

ndarray, optional

nz#

Element normal z-components

Type:

ndarray, optional

element_indices#

Original indices before any thinning (for tracking)

Type:

ndarray, optional

property n_elements: int#

Number of elements in the array.

property is_planar: bool#

Check if array is planar (all z and normals the same).

property is_conformal: bool#

Check if array has varying element orientations.

copy()[source]#

Create a deep copy of the geometry.

class phased_array.SubarrayArchitecture(geometry, subarray_assignments, n_subarrays, subarray_centers=None, overlapped=False, subarray_elements=None, overlap_weights=None)[source]#

Bases: object

Defines subarray partitioning of a phased array.

Supports both non-overlapped and overlapped subarray architectures. In overlapped architectures, elements can belong to multiple subarrays with potentially different weights.

geometry#

Full array geometry

Type:

ArrayGeometry

subarray_assignments#

Subarray index for each element (shape: n_elements,) None for overlapped subarrays

Type:

ndarray, optional

n_subarrays#

Number of subarrays

Type:

int

subarray_centers#

Center positions of each subarray (n_subarrays, 2 or 3)

Type:

ndarray, optional

overlapped#

True if this is an overlapped subarray architecture

Type:

bool

subarray_elements#

For overlapped: list of element indices for each subarray

Type:

list of ndarray, optional

overlap_weights#

For overlapped: amplitude weights for shared elements in each subarray

Type:

list of ndarray, optional

overlapped: bool = False#
subarray_elements: List[ndarray] | None = None#
overlap_weights: List[ndarray] | None = None#
get_subarray_elements(subarray_idx)[source]#

Get element indices and mask for a specific subarray.

get_element_subarrays(element_idx)[source]#

Get indices of all subarrays that contain a given element.

For non-overlapped architectures, returns single subarray index. For overlapped, may return multiple indices.

Parameters:

element_idx (int) – Index of the element

Returns:

subarray_indices – Array of subarray indices containing this element

Return type:

ndarray

Planar Arrays#

phased_array.create_rectangular_array(Nx, Ny, dx, dy, wavelength=1.0, center=True)[source]#

Create a rectangular planar array.

Parameters:
  • Nx (int) – Number of elements in x

  • Ny (int) – Number of elements in y

  • dx (float) – Element spacing in x (in wavelengths)

  • dy (float) – Element spacing in y (in wavelengths)

  • wavelength (float) – Wavelength in meters (converts spacing to meters)

  • center (bool) – If True, center array at origin

Returns:

geometry – Array geometry with element positions

Return type:

ArrayGeometry

Examples

Create a 16x16 array with half-wavelength spacing:

>>> import phased_array as pa
>>> geom = pa.create_rectangular_array(16, 16, dx=0.5, dy=0.5)
>>> geom.n_elements
256
>>> geom.x.shape
(256,)

Create a 10x10 array at 10 GHz (3 cm wavelength):

>>> geom = pa.create_rectangular_array(10, 10, dx=0.5, dy=0.5, wavelength=0.03)
>>> geom.n_elements
100

Access element positions:

>>> geom = pa.create_rectangular_array(4, 4, dx=0.5, dy=0.5)
>>> geom.is_planar
True
phased_array.create_triangular_array(Nx, Ny, dx, dy=None, wavelength=1.0, center=True)[source]#

Create an offset triangular (hexagonal) array.

Rows are offset by half the x-spacing for optimal packing.

Parameters:
  • Nx (int) – Approximate number of elements in x

  • Ny (int) – Number of rows in y

  • dx (float) – Element spacing in x (in wavelengths)

  • dy (float, optional) – Row spacing in y. Default: dx * sqrt(3)/2 for equilateral

  • wavelength (float) – Wavelength in meters

  • center (bool) – If True, center array at origin

Returns:

geometry

Return type:

ArrayGeometry

Examples

Create a triangular grid array (hexagonal packing):

>>> import phased_array as pa
>>> geom = pa.create_triangular_array(10, 10, dx=0.5)
>>> geom.n_elements  # Slightly fewer than 10x10 due to offset rows
95
>>> geom.is_planar
True

Triangular grids provide ~13% better packing efficiency:

>>> rect = pa.create_rectangular_array(10, 10, dx=0.5, dy=0.5)
>>> tri = pa.create_triangular_array(10, 10, dx=0.5)
>>> rect.n_elements > tri.n_elements  # Rect has more for same Nx, Ny
True
phased_array.create_elliptical_array(a, b, dx, dy=None, grid_type='rectangular', wavelength=1.0)[source]#

Create an array within an elliptical boundary.

Parameters:
  • a (float) – Ellipse semi-axis in x (in wavelengths)

  • b (float) – Ellipse semi-axis in y (in wavelengths)

  • dx (float) – Element spacing in x (in wavelengths)

  • dy (float, optional) – Element spacing in y (default: same as dx)

  • grid_type (str) – ‘rectangular’ or ‘triangular’

  • wavelength (float) – Wavelength in meters

Returns:

geometry

Return type:

ArrayGeometry

Circular and Ring Arrays#

phased_array.create_circular_array(n_elements, radius, wavelength=1.0, start_angle=0.0)[source]#

Create a circular (ring) array in the xy-plane.

Parameters:
  • n_elements (int) – Number of elements

  • radius (float) – Ring radius in wavelengths

  • wavelength (float) – Wavelength in meters

  • start_angle (float) – Starting angle in radians

Returns:

geometry

Return type:

ArrayGeometry

phased_array.create_concentric_rings_array(n_rings, elements_per_ring, ring_spacing, wavelength=1.0, include_center=True)[source]#

Create a concentric rings array.

Parameters:
  • n_rings (int) – Number of rings

  • elements_per_ring (int or list) – Elements per ring (int applies to all, list for custom)

  • ring_spacing (float) – Spacing between rings in wavelengths

  • wavelength (float) – Wavelength in meters

  • include_center (bool) – Include a center element

Returns:

geometry

Return type:

ArrayGeometry

Conformal Arrays#

phased_array.create_cylindrical_array(n_azimuth, n_vertical, radius, height, wavelength=1.0)[source]#

Create a cylindrical conformal array.

Elements are distributed on a cylinder surface with normals pointing radially outward.

Parameters:
  • n_azimuth (int) – Number of elements around circumference

  • n_vertical (int) – Number of vertical rings

  • radius (float) – Cylinder radius in wavelengths

  • height (float) – Cylinder height in wavelengths

  • wavelength (float) – Wavelength in meters

Returns:

geometry

Return type:

ArrayGeometry

phased_array.create_spherical_array(n_theta, n_phi, radius, theta_min=0.0, theta_max=1.5707963267948966, wavelength=1.0)[source]#

Create a spherical conformal array.

Parameters:
  • n_theta (int) – Number of elements in theta (elevation)

  • n_phi (int) – Number of elements in phi (azimuth)

  • radius (float) – Sphere radius in wavelengths

  • theta_min (float) – Minimum theta in radians (0 = north pole)

  • theta_max (float) – Maximum theta in radians

  • wavelength (float) – Wavelength in meters

Returns:

geometry

Return type:

ArrayGeometry

phased_array.array_factor_conformal(theta, phi, geometry, weights, k, element_pattern_func=None, **element_kwargs)[source]#

Compute array factor for conformal arrays with element orientation.

Each element’s contribution is weighted by its projected pattern in the observation direction.

Parameters:
  • theta (ndarray) – Observation theta angles in radians

  • phi (ndarray) – Observation phi angles in radians

  • geometry (ArrayGeometry) – Array geometry with element normals

  • weights (ndarray) – Complex element weights

  • k (float) – Wavenumber

  • element_pattern_func (callable, optional) – Element pattern function

  • **element_kwargs – Arguments for element pattern function

Returns:

AF – Array factor (same shape as theta)

Return type:

ndarray

Sparse/Thinned Arrays#

phased_array.thin_array_random(geometry, thinning_factor, seed=None)[source]#

Randomly thin an array by removing elements.

Parameters:
  • geometry (ArrayGeometry) – Original array geometry

  • thinning_factor (float) – Fraction of elements to keep (0 to 1)

  • seed (int, optional) – Random seed for reproducibility

Returns:

geometry – Thinned array geometry

Return type:

ArrayGeometry

phased_array.thin_array_density_tapered(geometry, density_func, seed=None)[source]#

Thin array with position-dependent density (statistical thinning).

Parameters:
  • geometry (ArrayGeometry) – Original array geometry

  • density_func (callable) – Function(x, y) -> probability of keeping each element (0 to 1)

  • seed (int, optional) – Random seed

Returns:

geometry – Thinned geometry

Return type:

ArrayGeometry

phased_array.thin_array_genetic_algorithm(geometry, n_target, objective_func, population_size=50, n_generations=100, mutation_rate=0.1, seed=None)[source]#

Optimize element selection using a genetic algorithm.

Parameters:
  • geometry (ArrayGeometry) – Original full array geometry

  • n_target (int) – Target number of elements to keep

  • objective_func (callable) – Function(ArrayGeometry) -> float to minimize

  • population_size (int) – GA population size

  • n_generations (int) – Number of generations

  • mutation_rate (float) – Probability of mutation per gene

  • seed (int, optional) – Random seed

Returns:

geometry – Optimized thinned geometry

Return type:

ArrayGeometry

Subarrays#

phased_array.create_rectangular_subarrays(Nx_total, Ny_total, Nx_sub, Ny_sub, dx, dy, wavelength=1.0)[source]#

Create rectangular subarrays from a rectangular array.

Parameters:
  • Nx_total (int) – Total elements in x

  • Ny_total (int) – Total elements in y

  • Nx_sub (int) – Elements per subarray in x

  • Ny_sub (int) – Elements per subarray in y

  • dx (float) – Element spacing in wavelengths

  • dy (float) – Element spacing in wavelengths

  • wavelength (float) – Wavelength in meters

Returns:

architecture

Return type:

SubarrayArchitecture

phased_array.compute_subarray_weights(architecture, k, theta0_deg, phi0_deg, intra_subarray_weights=None)[source]#

Compute element weights for subarray-level beamforming.

Phase is quantized to subarray centers (one phase shifter per subarray).

Parameters:
  • architecture (SubarrayArchitecture) – Subarray architecture

  • k (float) – Wavenumber

  • theta0_deg (float) – Steering direction in degrees

  • phi0_deg (float) – Steering direction in degrees

  • intra_subarray_weights (ndarray, optional) – Amplitude taper applied within each subarray

Returns:

weights – Complex weights for all elements

Return type:

ndarray