-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathplot_snr.py
179 lines (134 loc) · 4.81 KB
/
plot_snr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
"""
plot_link_mod: Link model plot
"""
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
tfk = tf.keras
tfkm = tf.keras.models
tfkl = tf.keras.layers
import tensorflow.keras.backend as K
from tqdm import trange
from models import ChanMod, DataFormat
from antenna import Elem3GPP, Elem3GPPMultiSector
# Paramters
bw = 400e6 # Bandwidth in Hz
nf = 6 # Noise figure in dB
bf_gain = 10*np.log10(64*16)-3 # Array gain
kT = -174 # Thermal noise in dB/Hz
tx_pow = 23 # TX power in dBm
npts = 100 # number of points for each (x,z) bin
aer_height=30 # Height of the aerial cell
downtilt = 10 # downtilt on terrestrial cells
# Number of x and z bins
nx = 40
nz = 20
# Range of x and z distances to test
xlim = np.array([0,500])
zlim = np.array([0,130])
def comp_pl_gain(pl, gain, pl_max):
"""
Computes the path loss with directional gain
Parameters
----------
pl : (nlink,npaths_max) array
Array of path losses for each path
gain : (nlink, npaths_max) array
Array of gains on each path
pl_max : scalar
Max path loss. Values below this are not considerd
Returns
-------
pl_dir : (nlink,) array
Effective path loss with directional gain
"""
n = pl.shape[0]
pl_dir = np.zeros(n)
for i in range(n):
I = np.where(pl[i,:] < pl_max - 0.1)[0]
if len(I) == 0:
pl_dir[i] = pl_max
else:
pl_gain = pl[i,I] - gain[i,I]
pl_dir[i] = -10*np.log10( np.sum(10**(-0.1*pl_gain) ) )
return pl_dir
# Construct the channel model object
model_dir = 'model_data'
K.clear_session()
chan_mod = ChanMod(model_dir=model_dir)
# Load the learned link classifier model
chan_mod.load_link_model()
# Load the learned path model
chan_mod.load_path_model(weights_fn='path_weights.h5')
pl_max = chan_mod.pl_max
cell_types = [ChanMod.terr_cell, ChanMod.aerial_cell]
cell_str = ['Terestrial', 'Aerial']
nplot = len(cell_types)
snr_med = np.zeros((nz,nx,nplot))
for iplot, cell_type0 in enumerate(cell_types):
# Print cell type
print('Simulating %s cell' % cell_str[iplot])
# Set the limits and x and z values to test
dx = np.linspace(xlim[0],xlim[1],nx)
dz = np.linspace(zlim[0],zlim[1],nz)
if cell_type0 == ChanMod.aerial_cell:
dz = dz - aer_height
# Create the BS elements
if cell_type0 == ChanMod.aerial_cell:
elem_gnb = Elem3GPP(theta0=0, thetabw=90, phibw=0)
else:
elem_gnb = Elem3GPPMultiSector(nsect=3,theta0=90+downtilt,\
thetabw=65,\
phi0=0, phibw=90)
elem_ue = Elem3GPP(theta0=180, thetabw=90, phibw=0)
# Convert to meshgrid
dxmat, dzmat = np.meshgrid(dx,dz)
dvec = np.zeros((nx*nz,3))
dvec[:,0] = dxmat.ravel()
dvec[:,2] = dzmat.ravel()
cell_type = np.tile(cell_type0, (nx*nz,))
# Loop over multiple trials
snr = np.zeros((nz,nx,npts))
for i in trange(npts):
# Generate random channels
pl, ang, dly = chan_mod.sample_path(dvec, cell_type)
# Compute the UE gain
ue_theta = ang[:,:,DataFormat.aoa_theta_ind]
ue_phi = ang[:,:,DataFormat.aoa_phi_ind]
gain_ue = elem_ue.response(ue_phi, ue_theta)
# Compute the gNB gain
gnb_theta = ang[:,:,DataFormat.aod_theta_ind]
gnb_phi = ang[:,:,DataFormat.aod_phi_ind]
gain_gnb = elem_ue.response(gnb_phi, gnb_theta)
gain_tot = gain_ue + gain_gnb
# Compute the directional gain and RX power
pl_gain = comp_pl_gain(pl, gain_tot, pl_max)
snri = tx_pow - pl_gain + bf_gain - kT - nf - 10*np.log10(bw)
# Create the data for the plot
snri = snri.reshape((nz,nx))
snri = np.flipud(snri)
snr[:,:,i] = snri
#print('iplot=%d i=%d' % (iplot, i))
# Get the median rx power
snr_med[:,:,iplot] = np.median(snr,axis=2)
# Plot the results
for iplot in range(nplot):
plt.subplot(1,nplot,iplot+1)
plt.imshow(snr_med[:,:,iplot],\
extent=[np.min(xlim),np.max(xlim),np.min(zlim),np.max(zlim)],\
aspect='auto', vmin=-20, vmax=40)
# Add horizontal line indicating location of aerial cell
if (cell_types[iplot] == ChanMod.aerial_cell):
plt.plot(xlim, np.array([1,1])*aer_height, 'r--')
if (iplot > 0):
plt.yticks([])
else:
plt.ylabel('Elevation (m)')
plt.xlabel('Horiz (m)')
plt.title(cell_str[iplot])
# Add the colorbar
plt.tight_layout()
plt.subplots_adjust(bottom=0.1, right=0.87, top=0.9)
cax = plt.axes([0.92, 0.1, 0.05, 0.8])
plt.colorbar(cax=cax)
plt.savefig('snr_dist.png', bbox_inches='tight')