/ 5_Simulations / array_pattern_Kaiser25dB_like.py
array_pattern_Kaiser25dB_like.py
  1  #!/usr/bin/env python3
  2  import numpy as np
  3  import matplotlib.pyplot as plt
  4  
  5  c0 = 299_792_458.0
  6  f0 = 10500000000.0
  7  lam0 = c0/f0
  8  k0 = 2*np.pi/lam0
  9  
 10  M = 16
 11  N = 32
 12  dy = 14.275831333333334/1e3
 13  dz = 16.915/1e3
 14  
 15  theta0_deg = 0.0
 16  phi0_deg   = 0.0
 17  theta0 = np.deg2rad(theta0_deg)
 18  phi0   = np.deg2rad(phi0_deg)
 19  
 20  beta = 1.65
 21  wy = np.ones(16, float)
 22  wz = np.kaiser(32, beta)
 23  wz /= wz.max()
 24  
 25  m_idx = np.arange(M) - (M-1)/2
 26  n_idx = np.arange(N) - (N-1)/2
 27  y_positions = m_idx * dy
 28  z_positions = n_idx * dz
 29  
 30  def element_factor(theta_rad, phi_rad):
 31      return np.abs(np.cos(theta_rad))
 32  
 33  def array_factor(theta_rad, phi_rad, y_positions, z_positions, wy, wz, theta0_rad, phi0_rad):
 34      k0 = 2*np.pi/(299_792_458.0/10500000000.0)
 35      ky = k0*np.sin(theta_rad)*np.sin(phi_rad)
 36      kz = k0*np.sin(theta_rad)*np.cos(phi_rad)
 37      ky0 = k0*np.sin(theta0_rad)*np.sin(phi0_rad)
 38      kz0 = k0*np.sin(theta0_rad)*np.cos(phi0_rad)
 39      Ay = np.sum(wy[:,None] * np.exp(1j * y_positions[:,None]*(ky[None,:]-ky0)), axis=0)
 40      Az = np.sum(wz[:,None] * np.exp(1j * z_positions[:,None]*(kz[None,:]-kz0)), axis=0)
 41      return Ay * Az
 42  
 43  def cut_curve(phi_deg, num_pts=721):
 44      th_deg = np.linspace(0, 90, num_pts)
 45      th = np.deg2rad(th_deg)
 46      ph = np.deg2rad(phi_deg) * np.ones_like(th)
 47      AF = array_factor(th, ph, y_positions, z_positions, wy, wz, theta0, phi0)
 48      PAT = np.abs(AF) * element_factor(th, ph)
 49      PAT /= PAT.max()
 50      return th_deg, 20*np.log10(PAT + 1e-15)
 51  
 52  def hpbw_deg(theta_deg, pat_db):
 53      p = np.argmax(pat_db)
 54      peak = pat_db[p]
 55      mask = pat_db >= (peak - 3.0)
 56      idx = np.where(mask)[0]
 57      if len(idx) < 2:
 58          return np.nan
 59      return float(theta_deg[idx[-1]] - theta_deg[idx[0]])
 60  
 61  thE_deg, patE_db = cut_curve(0.0)
 62  bwE = hpbw_deg(thE_deg, patE_db)
 63  plt.figure(figsize=(7,5), dpi=130)
 64  plt.plot(thE_deg, patE_db, linewidth=1.5)
 65  plt.grid(True, linestyle='--', alpha=0.5)
 66  plt.xlabel('Theta (deg)')
 67  plt.ylabel('Normalized Gain (dB)')
 68  plt.title(f'E-plane (phi=0°)  |  -3 dB BW ≈ {bwE:.2f}°')
 69  plt.tight_layout()
 70  plt.savefig('E_plane_Kaiser25dB_like.png', bbox_inches='tight')
 71  plt.show()
 72  
 73  thH_deg, patH_db = cut_curve(90.0)
 74  bwH = hpbw_deg(thH_deg, patH_db)
 75  plt.figure(figsize=(7,5), dpi=130)
 76  plt.plot(thH_deg, patH_db, linewidth=1.5)
 77  plt.grid(True, linestyle='--', alpha=0.5)
 78  plt.xlabel('Theta (deg)')
 79  plt.ylabel('Normalized Gain (dB)')
 80  plt.title(f'H-plane (phi=90°) |  -3 dB BW ≈ {bwH:.2f}°')
 81  plt.tight_layout()
 82  plt.savefig('H_plane_Kaiser25dB_like.png', bbox_inches='tight')
 83  plt.show()
 84  
 85  theta_deg = np.linspace(0.0, 90.0, 121)
 86  phi_deg   = np.linspace(-90.0, 90.0, 121)
 87  TH, PH = np.meshgrid(theta_deg, phi_deg, indexing='xy')
 88  PAT_db = np.empty_like(TH, dtype=float)
 89  for i in range(TH.shape[0]):
 90      th = np.deg2rad(TH[i, :])
 91      ph = np.deg2rad(PH[i, :])
 92      AF = array_factor(th, ph, y_positions, z_positions, wy, wz, theta0, phi0)
 93      EF = element_factor(th, ph)
 94      pat = np.abs(AF)*EF
 95      pat /= pat.max()
 96      PAT_db[i, :] = 20*np.log10(pat + 1e-15)
 97  
 98  plt.figure(figsize=(7,5), dpi=130)
 99  extent = [theta_deg[0], theta_deg[-1], phi_deg[0], phi_deg[-1]]
100  plt.imshow(PAT_db, origin='lower', extent=extent, aspect='auto')
101  plt.colorbar(label='Normalized Gain (dB)')
102  plt.xlabel('Theta (deg)')
103  plt.ylabel('Phi (deg)')
104  plt.title('Array Pattern Heatmap (|AF·EF|, dB) — Kaiser ~-25 dB')
105  plt.tight_layout()
106  plt.savefig('Heatmap_Kaiser25dB_like.png', bbox_inches='tight')
107  plt.show()
108  
109  print('Saved: E_plane_Kaiser25dB_like.png, H_plane_Kaiser25dB_like.png, Heatmap_Kaiser25dB_like.png')