11aa590cf2
Resolve all 374 ruff errors across 36 Python files (E501, E702, E722, E741, F821, F841, invalid-syntax) bringing `ruff check .` to zero errors repo-wide with line-length=100. Rewrite CI workflow to use uv for dependency management, whole-repo `ruff check .`, py_compile syntax gate, and merged python-tests job. Add pyproject.toml with ruff config and uv dependency groups. CI structure proposed by hcm444.
113 lines
3.4 KiB
Python
113 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
|
|
c0 = 299_792_458.0
|
|
f0 = 10500000000.0
|
|
lam0 = c0/f0
|
|
k0 = 2*np.pi/lam0
|
|
|
|
M = 16
|
|
N = 32
|
|
dy = 14.275831333333334/1e3
|
|
dz = 16.915/1e3
|
|
|
|
theta0_deg = 0.0
|
|
phi0_deg = 0.0
|
|
theta0 = np.deg2rad(theta0_deg)
|
|
phi0 = np.deg2rad(phi0_deg)
|
|
|
|
beta = 1.65
|
|
wy = np.ones(16, float)
|
|
wz = np.kaiser(32, beta)
|
|
wz /= wz.max()
|
|
|
|
m_idx = np.arange(M) - (M-1)/2
|
|
n_idx = np.arange(N) - (N-1)/2
|
|
y_positions = m_idx * dy
|
|
z_positions = n_idx * dz
|
|
|
|
def element_factor(theta_rad, phi_rad):
|
|
return np.abs(np.cos(theta_rad))
|
|
|
|
def array_factor(theta_rad, phi_rad, y_positions, z_positions, wy, wz, theta0_rad, phi0_rad):
|
|
k0 = 2*np.pi/(299_792_458.0/10500000000.0)
|
|
ky = k0*np.sin(theta_rad)*np.sin(phi_rad)
|
|
kz = k0*np.sin(theta_rad)*np.cos(phi_rad)
|
|
ky0 = k0*np.sin(theta0_rad)*np.sin(phi0_rad)
|
|
kz0 = k0*np.sin(theta0_rad)*np.cos(phi0_rad)
|
|
Ay = np.sum(wy[:,None] * np.exp(1j * y_positions[:,None]*(ky[None,:]-ky0)), axis=0)
|
|
Az = np.sum(wz[:,None] * np.exp(1j * z_positions[:,None]*(kz[None,:]-kz0)), axis=0)
|
|
return Ay * Az
|
|
|
|
def cut_curve(phi_deg, num_pts=721):
|
|
th_deg = np.linspace(0, 90, num_pts)
|
|
th = np.deg2rad(th_deg)
|
|
ph = np.deg2rad(phi_deg) * np.ones_like(th)
|
|
AF = array_factor(th, ph, y_positions, z_positions, wy, wz, theta0, phi0)
|
|
PAT = np.abs(AF) * element_factor(th, ph)
|
|
PAT /= PAT.max()
|
|
return th_deg, 20*np.log10(PAT + 1e-15)
|
|
|
|
def hpbw_deg(theta_deg, pat_db):
|
|
p = np.argmax(pat_db)
|
|
peak = pat_db[p]
|
|
mask = pat_db >= (peak - 3.0)
|
|
idx = np.where(mask)[0]
|
|
if len(idx) < 2:
|
|
return np.nan
|
|
return float(theta_deg[idx[-1]] - theta_deg[idx[0]])
|
|
|
|
thE_deg, patE_db = cut_curve(0.0)
|
|
bwE = hpbw_deg(thE_deg, patE_db)
|
|
plt.figure(figsize=(7,5), dpi=130)
|
|
plt.plot(thE_deg, patE_db, linewidth=1.5)
|
|
plt.grid(True, linestyle='--', alpha=0.5)
|
|
plt.xlabel('Theta (deg)')
|
|
plt.ylabel('Normalized Gain (dB)')
|
|
plt.title(f'E-plane (phi=0°) | -3 dB BW ≈ {bwE:.2f}°')
|
|
plt.tight_layout()
|
|
plt.savefig('E_plane_Kaiser25dB_like.png', bbox_inches='tight')
|
|
plt.show()
|
|
|
|
thH_deg, patH_db = cut_curve(90.0)
|
|
bwH = hpbw_deg(thH_deg, patH_db)
|
|
plt.figure(figsize=(7,5), dpi=130)
|
|
plt.plot(thH_deg, patH_db, linewidth=1.5)
|
|
plt.grid(True, linestyle='--', alpha=0.5)
|
|
plt.xlabel('Theta (deg)')
|
|
plt.ylabel('Normalized Gain (dB)')
|
|
plt.title(f'H-plane (phi=90°) | -3 dB BW ≈ {bwH:.2f}°')
|
|
plt.tight_layout()
|
|
plt.savefig('H_plane_Kaiser25dB_like.png', bbox_inches='tight')
|
|
plt.show()
|
|
|
|
theta_deg = np.linspace(0.0, 90.0, 121)
|
|
phi_deg = np.linspace(-90.0, 90.0, 121)
|
|
TH, PH = np.meshgrid(theta_deg, phi_deg, indexing='xy')
|
|
PAT_db = np.empty_like(TH, dtype=float)
|
|
for i in range(TH.shape[0]):
|
|
th = np.deg2rad(TH[i, :])
|
|
ph = np.deg2rad(PH[i, :])
|
|
AF = array_factor(th, ph, y_positions, z_positions, wy, wz, theta0, phi0)
|
|
EF = element_factor(th, ph)
|
|
pat = np.abs(AF)*EF
|
|
pat /= pat.max()
|
|
PAT_db[i, :] = 20*np.log10(pat + 1e-15)
|
|
|
|
plt.figure(figsize=(7,5), dpi=130)
|
|
extent = [theta_deg[0], theta_deg[-1], phi_deg[0], phi_deg[-1]]
|
|
plt.imshow(PAT_db, origin='lower', extent=extent, aspect='auto')
|
|
plt.colorbar(label='Normalized Gain (dB)')
|
|
plt.xlabel('Theta (deg)')
|
|
plt.ylabel('Phi (deg)')
|
|
plt.title('Array Pattern Heatmap (|AF·EF|, dB) — Kaiser ~-25 dB')
|
|
plt.tight_layout()
|
|
plt.savefig('Heatmap_Kaiser25dB_like.png', bbox_inches='tight')
|
|
plt.show()
|
|
|
|
print(
|
|
'Saved: E_plane_Kaiser25dB_like.png, H_plane_Kaiser25dB_like.png, '
|
|
'Heatmap_Kaiser25dB_like.png'
|
|
)
|