-
Notifications
You must be signed in to change notification settings - Fork 11
/
plot_angle_dist.py
169 lines (135 loc) · 4.64 KB
/
plot_angle_dist.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
"""
plot_angle_dist.py: Plots the angular distribution
For all the NLOS paths, the program:
* Computes the AoA and AoD relative to the LOS path
* Plots the empirical distribution of the relative angles as
a function of the distance
* Generates random angles with the same conditions as the model,
and plots the relative angle as a function of the distance
for comparison.
"""
import numpy as np
import matplotlib.pyplot as plt
import pickle
import tensorflow.keras.backend as K
from models import ChanMod, DataFormat, get_link_state
def plot_ang_dist(chan_mod,dvec,nlos_ang,nlos_pl,iang,np_plot=10):
"""
Plots the conditional distribution of the relative angle.
Parameters
----------
chan_mod : ChanMod structure
Channel model.
dvec : (nlink,ndim) array
vector from cell to UAV
nlos_ang : (nlink,npaths_max,nangle) array
Angles of each path in each link.
The angles are in degrees
nlos_pl : (nlink,npaths_max) array
Path losses of each path in each link.
A value of pl_max indicates no path
iang: integer from 0 to DataFormat.nangle-1
Index of the angle to be plotted
np_plot: integer
Number of paths whose angles are to be plotted
"""
# Get the distances
np_plot = 10
dist = np.sqrt(np.sum(dvec**2,axis=1))
dist_plot = np.tile(dist[:,None],(1,np_plot))
dist_plot = dist_plot.ravel()
# Transform the angles. The transformations compute the
# relative angles and scales them by 180
ang_tr = chan_mod.transform_ang(dvec, nlos_ang, nlos_pl)
# Get the relative angle
np_max = chan_mod.npaths_max
ang_rel = ang_tr[:,iang*np_max:iang*np_max+np_plot]*180
ang_rel = ang_rel.ravel()
# Set the angle and distance range for the historgram
drange = [0,600]
if iang==DataFormat.aoa_phi_ind or iang==DataFormat.aod_phi_ind:
ang_range = [-180,180]
elif iang==DataFormat.aoa_theta_ind or iang==DataFormat.aod_theta_ind:
ang_range = [-90,90]
else:
raise ValueError('Invalid angle index')
# Compute the emperical conditional probability
H0, dedges, ang_edges = np.histogram2d(dist_plot,ang_rel,bins=[10,40],\
range=[drange,ang_range])
Hsum = np.sum(H0,axis=1)
H0 = H0 / Hsum[:,None]
# Plot the log probability.
# We plot the log proability since the probability in linear
# scale is difficult to view
log_prob = np.log10(np.maximum(0.01,H0.T))
plt.imshow(log_prob, extent=[np.min(dedges),np.max(dedges),\
np.min(ang_edges),np.max(ang_edges)], aspect='auto')
"""
Parameters
"""
fmt = 'eps'
"""
Load the true data
"""
# Load the data
fn = 'train_test_data.p'
with open(fn, 'rb') as fp:
train_data,test_data,pl_max = pickle.load(fp)
# Get the variables
dat = test_data
# Find the links where there is at least one valid path (either LOS or NLOS)
chan_mod0 = ChanMod()
ls = get_link_state(dat['los_exists'], dat['nlos_pl'], pl_max)
Ilink = np.where(ls != ChanMod.no_link)[0]
# Get the data from these links
dvec = dat['dvec'][Ilink]
los_ang = dat['los_ang'][Ilink]
nlos_ang = dat['nlos_ang'][Ilink]
nlos_pl = dat['nlos_pl'][Ilink]
ls = ls[Ilink]
"""
Generate synthentic data from trained model
"""
# Model directory
model_dir = 'model_data'
# Construct the channel model object
K.clear_session()
chan_mod = ChanMod(pl_max=pl_max,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()
# Sample from the same conditions as the data
nlos_pl_rand, nlos_ang_rand, nlos_dly_rand = chan_mod.sample_path(dvec,\
dat['cell_type'][Ilink], ls, nlos_only=True)
"""
Plot the angular distributions
"""
plt.rcParams.update({'font.size': 16})
plt.figure(figsize=[10,10])
ang_str = ['AoA Az', 'AoA El', 'AoD Az', 'AoD El']
for iang in range(4):
plt.subplot(4,2,2*iang+1)
plot_ang_dist(chan_mod0,dvec,nlos_ang,nlos_pl,iang)
if iang < 3:
plt.xticks([])
else:
plt.xlabel('Dist (m)')
title_str = ang_str[iang] + ' Data'
plt.title(title_str)
plt.subplot(4,2,2*iang+2)
plot_ang_dist(chan_mod,dvec,nlos_ang_rand,nlos_pl_rand,iang)
if iang < 3:
plt.xticks([])
else:
plt.xlabel('Dist (m)')
title_str = ang_str[iang] + ' Model'
plt.title(title_str)
plt.tight_layout()
if 0:
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)
# Print image
fn = 'angle_dist.' + fmt
plt.savefig(fn)