DeepMIMO 2.0__tar.gz → 3.2.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {deepmimo-2.0 → deepmimo-3.2.9}/PKG-INFO +9 -4
- {deepmimo-2.0 → deepmimo-3.2.9}/README.md +10 -0
- deepmimo-3.2.9/setup.py +36 -0
- {deepmimo-2.0 → deepmimo-3.2.9}/src/DeepMIMO.egg-info/PKG-INFO +9 -4
- deepmimo-3.2.9/src/DeepMIMO.egg-info/SOURCES.txt +19 -0
- {deepmimo-2.0 → deepmimo-3.2.9}/src/DeepMIMO.egg-info/requires.txt +1 -0
- deepmimo-3.2.9/src/DeepMIMO.egg-info/top_level.txt +1 -0
- deepmimo-3.2.9/src/DeepMIMOv3/__init__.py +4 -0
- {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/ant_patterns.py +1 -1
- {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/construct_deepmimo.py +102 -25
- {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/consts.py +23 -9
- {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/generator.py +120 -47
- {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/params.py +13 -16
- deepmimo-2.0/src/DeepMIMO/raytracing.py → deepmimo-3.2.9/src/DeepMIMOv3/raytracing_v2.py +62 -38
- deepmimo-3.2.9/src/DeepMIMOv3/raytracing_v3.py +182 -0
- deepmimo-3.2.9/src/DeepMIMOv3/utils.py +292 -0
- deepmimo-3.2.9/src/DeepMIMOv3/visualization.py +259 -0
- deepmimo-2.0/setup.py +0 -30
- deepmimo-2.0/src/DeepMIMO/__init__.py +0 -4
- deepmimo-2.0/src/DeepMIMO/file_loaders.py +0 -59
- deepmimo-2.0/src/DeepMIMO/utils.py +0 -16
- deepmimo-2.0/src/DeepMIMO.egg-info/SOURCES.txt +0 -18
- deepmimo-2.0/src/DeepMIMO.egg-info/top_level.txt +0 -1
- {deepmimo-2.0 → deepmimo-3.2.9}/LICENSE.md +0 -0
- {deepmimo-2.0 → deepmimo-3.2.9}/setup.cfg +0 -0
- {deepmimo-2.0 → deepmimo-3.2.9}/src/DeepMIMO.egg-info/dependency_links.txt +0 -0
- {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/sionna_adapter.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DeepMIMO
|
|
3
|
-
Version: 2.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 3.2.9
|
|
4
|
+
Summary: DeepMIMOv3
|
|
5
5
|
Home-page: https://deepmimo.net/
|
|
6
6
|
Author: Umut Demirhan, Ahmed Alkhateeb
|
|
7
7
|
Keywords: mmWave,MIMO,DeepMIMO,python,Beta
|
|
8
|
-
Classifier: Development Status ::
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
@@ -13,6 +13,7 @@ License-File: LICENSE.md
|
|
|
13
13
|
Requires-Dist: numpy
|
|
14
14
|
Requires-Dist: scipy
|
|
15
15
|
Requires-Dist: tqdm
|
|
16
|
+
Requires-Dist: matplotlib
|
|
16
17
|
Dynamic: author
|
|
17
18
|
Dynamic: classifier
|
|
18
19
|
Dynamic: description
|
|
@@ -23,4 +24,8 @@ Dynamic: license-file
|
|
|
23
24
|
Dynamic: requires-dist
|
|
24
25
|
Dynamic: summary
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
This package contains Python code for DeepMIMOv3 generator library.
|
|
30
|
+
|
|
31
|
+
Install the lastest v3 package with: `pip install deepmimo==3`
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## ⚠️ Archived Repository Notice
|
|
2
|
+
|
|
3
|
+
**This repository has been archived** and is no longer maintained. It contains Python code for DeepMIMOv2 and DeepMIMOv3.
|
|
4
|
+
|
|
5
|
+
All future versions are now maintained in the [DeepMIMO Unified Repository](https://github.com/DeepMIMO/DeepMIMO)
|
|
6
|
+
|
|
7
|
+
DeepMIMOv4 is being developed in this repository and will be made public in May 2025.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
1
11
|
# DeepMIMO: A Generic Deep Learning Dataset for Millimeter Wave and Massive MIMO Applications
|
|
2
12
|
This is a python code package of the DeepMIMO dataset generated using [Remcom Wireless InSite](http://www.remcom.com/wireless-insite) software. The [DeepMIMO dataset](https://deepmimo.net/) is a publicly available parameterized dataset published for deep learning applications in mmWave and massive MIMO systems.
|
|
3
13
|
|
deepmimo-3.2.9/setup.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import setuptools
|
|
2
|
+
|
|
3
|
+
VERSION = '3.2.9'
|
|
4
|
+
DESCRIPTION = 'DeepMIMOv3'
|
|
5
|
+
LONG_DESCRIPTION = """
|
|
6
|
+
|
|
7
|
+
This package contains Python code for DeepMIMOv3 generator library.
|
|
8
|
+
|
|
9
|
+
Install the lastest v3 package with: `pip install deepmimo==3`
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# Setting up
|
|
13
|
+
setuptools.setup(
|
|
14
|
+
name="DeepMIMO",
|
|
15
|
+
version=VERSION,
|
|
16
|
+
author="Umut Demirhan, Ahmed Alkhateeb",
|
|
17
|
+
description=DESCRIPTION,
|
|
18
|
+
long_description=LONG_DESCRIPTION,
|
|
19
|
+
long_description_content_type="text/markdown",
|
|
20
|
+
license_files=('LICENSE.md',),
|
|
21
|
+
install_requires=[
|
|
22
|
+
'numpy',
|
|
23
|
+
'scipy',
|
|
24
|
+
'tqdm',
|
|
25
|
+
'matplotlib',
|
|
26
|
+
],
|
|
27
|
+
keywords=['mmWave', 'MIMO', 'DeepMIMO', 'python', 'Beta'],
|
|
28
|
+
classifiers=[
|
|
29
|
+
"Development Status :: 3 - Alpha",
|
|
30
|
+
"Programming Language :: Python :: 3",
|
|
31
|
+
"Operating System :: OS Independent"
|
|
32
|
+
],
|
|
33
|
+
package_dir={"": "src"},
|
|
34
|
+
packages=setuptools.find_packages(where="src"),
|
|
35
|
+
url='https://deepmimo.net/'
|
|
36
|
+
)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DeepMIMO
|
|
3
|
-
Version: 2.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 3.2.9
|
|
4
|
+
Summary: DeepMIMOv3
|
|
5
5
|
Home-page: https://deepmimo.net/
|
|
6
6
|
Author: Umut Demirhan, Ahmed Alkhateeb
|
|
7
7
|
Keywords: mmWave,MIMO,DeepMIMO,python,Beta
|
|
8
|
-
Classifier: Development Status ::
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
@@ -13,6 +13,7 @@ License-File: LICENSE.md
|
|
|
13
13
|
Requires-Dist: numpy
|
|
14
14
|
Requires-Dist: scipy
|
|
15
15
|
Requires-Dist: tqdm
|
|
16
|
+
Requires-Dist: matplotlib
|
|
16
17
|
Dynamic: author
|
|
17
18
|
Dynamic: classifier
|
|
18
19
|
Dynamic: description
|
|
@@ -23,4 +24,8 @@ Dynamic: license-file
|
|
|
23
24
|
Dynamic: requires-dist
|
|
24
25
|
Dynamic: summary
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
This package contains Python code for DeepMIMOv3 generator library.
|
|
30
|
+
|
|
31
|
+
Install the lastest v3 package with: `pip install deepmimo==3`
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
LICENSE.md
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
src/DeepMIMO.egg-info/PKG-INFO
|
|
5
|
+
src/DeepMIMO.egg-info/SOURCES.txt
|
|
6
|
+
src/DeepMIMO.egg-info/dependency_links.txt
|
|
7
|
+
src/DeepMIMO.egg-info/requires.txt
|
|
8
|
+
src/DeepMIMO.egg-info/top_level.txt
|
|
9
|
+
src/DeepMIMOv3/__init__.py
|
|
10
|
+
src/DeepMIMOv3/ant_patterns.py
|
|
11
|
+
src/DeepMIMOv3/construct_deepmimo.py
|
|
12
|
+
src/DeepMIMOv3/consts.py
|
|
13
|
+
src/DeepMIMOv3/generator.py
|
|
14
|
+
src/DeepMIMOv3/params.py
|
|
15
|
+
src/DeepMIMOv3/raytracing_v2.py
|
|
16
|
+
src/DeepMIMOv3/raytracing_v3.py
|
|
17
|
+
src/DeepMIMOv3/sionna_adapter.py
|
|
18
|
+
src/DeepMIMOv3/utils.py
|
|
19
|
+
src/DeepMIMOv3/visualization.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DeepMIMOv3
|
|
@@ -8,11 +8,10 @@ Authors: Umut Demirhan, Ahmed Alkhateeb
|
|
|
8
8
|
Date: 12/10/2021
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
import
|
|
11
|
+
import DeepMIMOv3.consts as c
|
|
12
12
|
import numpy as np
|
|
13
13
|
from tqdm import tqdm
|
|
14
|
-
import
|
|
15
|
-
from DeepMIMO.ant_patterns import AntennaPattern
|
|
14
|
+
from DeepMIMOv3.ant_patterns import AntennaPattern
|
|
16
15
|
|
|
17
16
|
# Generates common parameters first. The output is a numpy matrix.
|
|
18
17
|
def generate_MIMO_channel(raydata, params, tx_ant_params, rx_ant_params):
|
|
@@ -22,8 +21,8 @@ def generate_MIMO_channel(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
22
21
|
kd_tx = 2*np.pi*tx_ant_params[c.PARAMSET_ANT_SPACING]
|
|
23
22
|
kd_rx = 2*np.pi*rx_ant_params[c.PARAMSET_ANT_SPACING]
|
|
24
23
|
Ts = 1/bandwidth
|
|
25
|
-
subcarriers =
|
|
26
|
-
path_gen = OFDM_PathGenerator(params
|
|
24
|
+
subcarriers = params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_SC_SAMP]
|
|
25
|
+
path_gen = OFDM_PathGenerator(params, subcarriers)
|
|
27
26
|
antennapattern = AntennaPattern(tx_pattern = tx_ant_params[c.PARAMSET_ANT_RAD_PAT], rx_pattern = rx_ant_params[c.PARAMSET_ANT_RAD_PAT])
|
|
28
27
|
|
|
29
28
|
M_tx = np.prod(tx_ant_params[c.PARAMSET_ANT_SHAPE])
|
|
@@ -36,10 +35,12 @@ def generate_MIMO_channel(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
36
35
|
channel = np.zeros((len(raydata), M_rx, M_tx, len(subcarriers)), dtype = np.csingle)
|
|
37
36
|
else:
|
|
38
37
|
channel = np.zeros((len(raydata), M_rx, M_tx, params[c.PARAMSET_NUM_PATHS]), dtype = np.csingle)
|
|
38
|
+
LoS_status = np.zeros((len(raydata)), dtype=np.int8)-2
|
|
39
39
|
|
|
40
40
|
for i in tqdm(range(len(raydata)), desc='Generating channels'):
|
|
41
41
|
|
|
42
42
|
if raydata[i][c.OUT_PATH_NUM]==0:
|
|
43
|
+
LoS_status[i] = -1
|
|
43
44
|
continue
|
|
44
45
|
|
|
45
46
|
|
|
@@ -51,6 +52,25 @@ def generate_MIMO_channel(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
51
52
|
theta = raydata[i][c.OUT_PATH_DOA_THETA],
|
|
52
53
|
phi = raydata[i][c.OUT_PATH_DOA_PHI])
|
|
53
54
|
|
|
55
|
+
FoV_tx = apply_FoV(tx_ant_params[c.PARAMSET_ANT_FOV], dod_theta, dod_phi)
|
|
56
|
+
FoV_rx = apply_FoV(rx_ant_params[c.PARAMSET_ANT_FOV], doa_theta, doa_phi)
|
|
57
|
+
FoV = np.logical_and(FoV_tx, FoV_rx)
|
|
58
|
+
dod_theta = dod_theta[FoV]
|
|
59
|
+
dod_phi = dod_phi[FoV]
|
|
60
|
+
doa_theta = doa_theta[FoV]
|
|
61
|
+
doa_phi = doa_phi[FoV]
|
|
62
|
+
|
|
63
|
+
for key in raydata[i].keys():
|
|
64
|
+
if key == 'num_paths':
|
|
65
|
+
raydata[i][key] = FoV.sum()
|
|
66
|
+
else:
|
|
67
|
+
raydata[i][key] = raydata[i][key][FoV]
|
|
68
|
+
|
|
69
|
+
if raydata[i]['num_paths'] == 0:
|
|
70
|
+
LoS_status[i] = -1
|
|
71
|
+
else:
|
|
72
|
+
LoS_status[i] = raydata[i]['LoS'].sum()
|
|
73
|
+
|
|
54
74
|
array_response_TX = array_response(ant_ind = ant_tx_ind,
|
|
55
75
|
theta = dod_theta,
|
|
56
76
|
phi = dod_phi,
|
|
@@ -66,11 +86,10 @@ def generate_MIMO_channel(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
66
86
|
doa_phi = doa_phi,
|
|
67
87
|
dod_theta = dod_theta,
|
|
68
88
|
dod_phi = dod_phi)
|
|
89
|
+
raydata[i][c.OUT_PATH_RX_POW] = power
|
|
69
90
|
|
|
70
91
|
if params[c.PARAMSET_FDTD]: # OFDM
|
|
71
|
-
path_const = path_gen.generate(
|
|
72
|
-
(raydata[i][c.OUT_PATH_TOA]/Ts).reshape(-1, 1),
|
|
73
|
-
raydata[i][c.OUT_PATH_PHASE].reshape(-1,1))
|
|
92
|
+
path_const = path_gen.generate(raydata[i], Ts)
|
|
74
93
|
|
|
75
94
|
# The next step is to be defined
|
|
76
95
|
if params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_LPF] == 0:
|
|
@@ -81,7 +100,7 @@ def generate_MIMO_channel(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
81
100
|
else: # TD channel
|
|
82
101
|
channel[i, :, :, :raydata[i][c.OUT_PATH_NUM]] = array_response_RX[:, None, :] * array_response_TX[None, :, :] * (np.sqrt(power) * np.exp(1j*np.deg2rad(raydata[i][c.OUT_PATH_PHASE])))[None, None, :]
|
|
83
102
|
|
|
84
|
-
return channel
|
|
103
|
+
return channel, LoS_status
|
|
85
104
|
|
|
86
105
|
# Generates everything for each rx_ant_params -
|
|
87
106
|
# necessary for BS-BS channels since different antennas can be defined.
|
|
@@ -91,11 +110,12 @@ def generate_MIMO_channel_rx_ind(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
91
110
|
bandwidth = params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_BW] * c.PARAMSET_OFDM_BW_MULT
|
|
92
111
|
|
|
93
112
|
Ts = 1/bandwidth
|
|
94
|
-
subcarriers =
|
|
95
|
-
path_gen = OFDM_PathGenerator(params
|
|
113
|
+
subcarriers = params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_SC_SAMP]
|
|
114
|
+
path_gen = OFDM_PathGenerator(params, subcarriers)
|
|
96
115
|
|
|
97
116
|
|
|
98
117
|
channel = []
|
|
118
|
+
LoS_status = []
|
|
99
119
|
|
|
100
120
|
for i in tqdm(range(len(raydata)), desc='Generating channels'):
|
|
101
121
|
|
|
@@ -112,6 +132,7 @@ def generate_MIMO_channel_rx_ind(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
112
132
|
|
|
113
133
|
if raydata[i][c.OUT_PATH_NUM]==0:
|
|
114
134
|
channel.append(np.zeros((M_rx, M_tx, len(subcarriers))))
|
|
135
|
+
LoS_status.append(-1)
|
|
115
136
|
continue
|
|
116
137
|
|
|
117
138
|
|
|
@@ -122,7 +143,26 @@ def generate_MIMO_channel_rx_ind(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
122
143
|
doa_theta, doa_phi = rotate_angles(rotation = rx_ant_params[i][c.PARAMSET_ANT_ROTATION],
|
|
123
144
|
theta = raydata[i][c.OUT_PATH_DOA_THETA],
|
|
124
145
|
phi = raydata[i][c.OUT_PATH_DOA_PHI])
|
|
146
|
+
|
|
147
|
+
FoV_tx = apply_FoV(tx_ant_params[c.PARAMSET_ANT_FOV], dod_theta, dod_phi)
|
|
148
|
+
FoV_rx = apply_FoV(rx_ant_params[i][c.PARAMSET_ANT_FOV], doa_theta, doa_phi)
|
|
149
|
+
FoV = np.logical_and(FoV_tx, FoV_rx)
|
|
150
|
+
dod_theta = dod_theta[FoV]
|
|
151
|
+
dod_phi = dod_phi[FoV]
|
|
152
|
+
doa_theta = doa_theta[FoV]
|
|
153
|
+
doa_phi = doa_phi[FoV]
|
|
154
|
+
|
|
155
|
+
for key in raydata[i].keys():
|
|
156
|
+
if key == 'num_paths':
|
|
157
|
+
raydata[i][key] = FoV.sum()
|
|
158
|
+
else:
|
|
159
|
+
raydata[i][key] = raydata[i][key][FoV]
|
|
125
160
|
|
|
161
|
+
if raydata[i]['num_paths'] == 0:
|
|
162
|
+
LoS_status.append(-1)
|
|
163
|
+
else:
|
|
164
|
+
LoS_status.append(raydata[i]['LoS'].sum())
|
|
165
|
+
|
|
126
166
|
array_response_TX = array_response(ant_ind = ant_tx_ind,
|
|
127
167
|
theta = dod_theta,
|
|
128
168
|
phi = dod_phi,
|
|
@@ -138,11 +178,10 @@ def generate_MIMO_channel_rx_ind(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
138
178
|
doa_phi = doa_phi,
|
|
139
179
|
dod_theta = dod_theta,
|
|
140
180
|
dod_phi = dod_phi)
|
|
181
|
+
raydata[i][c.OUT_PATH_RX_POW] = power
|
|
141
182
|
|
|
142
183
|
if params[c.PARAMSET_FDTD]: # OFDM
|
|
143
|
-
path_const = path_gen.generate(
|
|
144
|
-
(raydata[i][c.OUT_PATH_TOA]/Ts).reshape(-1, 1),
|
|
145
|
-
raydata[i][c.OUT_PATH_PHASE].reshape(-1,1))
|
|
184
|
+
path_const = path_gen.generate(raydata[i], Ts)
|
|
146
185
|
|
|
147
186
|
# The next step is to be defined
|
|
148
187
|
if params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_LPF] == 0: # NO LPF
|
|
@@ -153,7 +192,7 @@ def generate_MIMO_channel_rx_ind(raydata, params, tx_ant_params, rx_ant_params):
|
|
|
153
192
|
else: # Time domain
|
|
154
193
|
channel.append(array_response_RX[:, None, :] * array_response_TX[None, :, :] * (np.sqrt(power) * np.exp(1j*np.deg2rad(raydata[i][c.OUT_PATH_PHASE])))[None, None, :])
|
|
155
194
|
|
|
156
|
-
return channel
|
|
195
|
+
return channel, LoS_status
|
|
157
196
|
|
|
158
197
|
|
|
159
198
|
def array_response(ant_ind, theta, phi, kd):
|
|
@@ -167,11 +206,20 @@ def array_response_phase(theta, phi, kd):
|
|
|
167
206
|
return np.vstack([gamma_x, gamma_y, gamma_z]).T
|
|
168
207
|
|
|
169
208
|
def ant_indices(panel_size):
|
|
170
|
-
gamma_x = np.tile(np.arange(
|
|
171
|
-
gamma_y = np.tile(np.repeat(np.arange(panel_size[
|
|
172
|
-
gamma_z = np.repeat(np.arange(panel_size[
|
|
209
|
+
gamma_x = np.tile(np.arange(1), panel_size[0]*panel_size[1])
|
|
210
|
+
gamma_y = np.tile(np.repeat(np.arange(panel_size[0]), 1), panel_size[1])
|
|
211
|
+
gamma_z = np.repeat(np.arange(panel_size[1]), panel_size[0])
|
|
173
212
|
return np.vstack([gamma_x, gamma_y, gamma_z]).T
|
|
174
213
|
|
|
214
|
+
def apply_FoV(FoV, theta, phi):
|
|
215
|
+
theta = np.mod(theta, 2*np.pi)
|
|
216
|
+
phi = np.mod(phi, 2*np.pi)
|
|
217
|
+
FoV = np.deg2rad(FoV)
|
|
218
|
+
path_inclusion_phi = np.logical_or(phi <= 0+FoV[0]/2, phi >= 2*np.pi-FoV[0]/2)
|
|
219
|
+
path_inclusion_theta = np.logical_and(theta <= np.pi/2+FoV[1]/2, theta >= np.pi/2-FoV[1]/2)
|
|
220
|
+
path_inclusion = np.logical_and(path_inclusion_phi, path_inclusion_theta)
|
|
221
|
+
return path_inclusion
|
|
222
|
+
|
|
175
223
|
def rotate_angles(rotation, theta, phi): # Input all degrees - output radians
|
|
176
224
|
theta = np.deg2rad(theta)
|
|
177
225
|
phi = np.deg2rad(phi)
|
|
@@ -199,29 +247,48 @@ def rotate_angles(rotation, theta, phi): # Input all degrees - output radians
|
|
|
199
247
|
return theta, phi
|
|
200
248
|
|
|
201
249
|
class OFDM_PathGenerator:
|
|
202
|
-
def __init__(self,
|
|
203
|
-
self.
|
|
250
|
+
def __init__(self, params, subcarriers):
|
|
251
|
+
self.params = params
|
|
252
|
+
self.OFDM_params = params[c.PARAMSET_OFDM]
|
|
204
253
|
|
|
205
|
-
if OFDM_params[c.PARAMSET_OFDM_LPF] == 0: # No Pulse Shaping
|
|
254
|
+
if self.OFDM_params[c.PARAMSET_OFDM_LPF] == 0: # No Pulse Shaping
|
|
206
255
|
self.generate = getattr(self, 'no_LPF')
|
|
207
256
|
else: # Pulse Shaping
|
|
208
257
|
self.generate = getattr(self, 'with_LPF')
|
|
209
258
|
|
|
210
259
|
|
|
211
260
|
self.subcarriers = subcarriers
|
|
212
|
-
self.total_subcarriers = OFDM_params[c.PARAMSET_OFDM_SC_NUM]
|
|
261
|
+
self.total_subcarriers = self.OFDM_params[c.PARAMSET_OFDM_SC_NUM]
|
|
213
262
|
|
|
214
263
|
self.delay_d = np.arange(self.OFDM_params['subcarriers'])
|
|
215
264
|
self.delay_to_OFDM = np.exp(-1j*2*np.pi/self.total_subcarriers*np.outer(self.delay_d, self.subcarriers))
|
|
216
265
|
|
|
217
|
-
def no_LPF(self,
|
|
266
|
+
def no_LPF(self, raydata, Ts):
|
|
267
|
+
power = (raydata[c.OUT_PATH_RX_POW]).reshape(-1, 1)
|
|
268
|
+
delay_n = (raydata[c.OUT_PATH_TOA]/Ts).reshape(-1, 1)
|
|
269
|
+
phase = raydata[c.OUT_PATH_PHASE].reshape(-1,1)
|
|
270
|
+
|
|
218
271
|
paths_over_FFT = (delay_n >= self.OFDM_params['subcarriers'])
|
|
219
272
|
power[paths_over_FFT] = 0
|
|
220
273
|
delay_n[paths_over_FFT] = self.OFDM_params['subcarriers']
|
|
221
274
|
|
|
222
|
-
|
|
275
|
+
path_const = np.sqrt(power/self.total_subcarriers) * np.exp(1j*(np.deg2rad(phase) - (2*np.pi/self.total_subcarriers)*np.outer(delay_n, self.subcarriers) ))
|
|
276
|
+
|
|
277
|
+
if self.params[c.PARAMSET_DOPPLER_EN] and self.params[c.PARAMSET_SCENARIO_PARAMS][c.PARAMSET_SCENARIO_PARAMS_DOPPLER_EN]:
|
|
278
|
+
doppler_vel = raydata[c.OUT_PATH_DOP_VEL].reshape(-1, 1)
|
|
279
|
+
doppler_acc = raydata[c.OUT_PATH_DOP_ACC].reshape(-1, 1)
|
|
280
|
+
carr_freq = self.params[c.PARAMSET_SCENARIO_PARAMS][c.PARAMSET_SCENARIO_PARAMS_CF]
|
|
281
|
+
|
|
282
|
+
delay = (raydata[c.OUT_PATH_TOA]).reshape(-1, 1)
|
|
283
|
+
Doppler_phase = np.exp(-1j*2*np.pi*carr_freq*(doppler_vel*delay/c.LIGHTSPEED + doppler_acc*(delay**2)/(2*c.LIGHTSPEED)))
|
|
284
|
+
path_const *= Doppler_phase
|
|
285
|
+
|
|
286
|
+
return path_const
|
|
223
287
|
|
|
224
|
-
def with_LPF(self,
|
|
288
|
+
def with_LPF(self, raydata, Ts):
|
|
289
|
+
power = (raydata[c.OUT_PATH_RX_POW]).reshape(-1, 1)
|
|
290
|
+
delay_n = (raydata[c.OUT_PATH_TOA]/Ts).reshape(-1, 1)
|
|
291
|
+
phase = raydata[c.OUT_PATH_PHASE].reshape(-1,1)
|
|
225
292
|
|
|
226
293
|
# Ignore the paths over CP
|
|
227
294
|
paths_over_FFT = (delay_n >= self.OFDM_params['subcarriers'])
|
|
@@ -231,5 +298,15 @@ class OFDM_PathGenerator:
|
|
|
231
298
|
# Pulse - LPF convolution and channel generation
|
|
232
299
|
pulse = np.sinc(self.delay_d-delay_n)
|
|
233
300
|
pulse = pulse * np.sqrt(power/self.total_subcarriers) * np.exp(1j*np.deg2rad(phase)) # Power scaling
|
|
301
|
+
|
|
302
|
+
if self.params[c.PARAMSET_DOPPLER_EN] and self.params[c.PARAMSET_SCENARIO_PARAMS][c.PARAMSET_SCENARIO_PARAMS_DOPPLER_EN]:
|
|
303
|
+
doppler_vel = raydata[c.OUT_PATH_DOP_VEL].reshape(-1, 1)
|
|
304
|
+
doppler_acc = raydata[c.OUT_PATH_DOP_ACC].reshape(-1, 1)
|
|
305
|
+
carr_freq = self.params[c.PARAMSET_SCENARIO_PARAMS][c.PARAMSET_SCENARIO_PARAMS_CF]
|
|
306
|
+
|
|
307
|
+
delay = Ts * self.delay_d.T
|
|
308
|
+
Doppler_phase = np.exp(-1j*2*np.pi*carr_freq*(doppler_vel*delay/c.LIGHTSPEED + doppler_acc*(delay**2)/(2*c.LIGHTSPEED)))
|
|
309
|
+
pulse *= Doppler_phase
|
|
310
|
+
|
|
234
311
|
return pulse
|
|
235
312
|
|
|
@@ -14,24 +14,26 @@ DICT_BS_IDX = 'basestation'
|
|
|
14
14
|
# NAME OF PARAMETER VARIABLES
|
|
15
15
|
PARAMSET_DATASET_FOLDER = 'dataset_folder'
|
|
16
16
|
PARAMSET_SCENARIO = 'scenario'
|
|
17
|
-
|
|
18
|
-
PARAMSET_DYNAMIC_FIRST = 'first_scene'
|
|
19
|
-
PARAMSET_DYNAMIC_LAST = 'last_scene'
|
|
17
|
+
PARAMSET_DYNAMIC_SCENES = 'dynamic_scenario_scenes'
|
|
20
18
|
|
|
21
19
|
PARAMSET_NUM_PATHS = 'num_paths'
|
|
22
20
|
PARAMSET_ACTIVE_BS = 'active_BS'
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
PARAMSET_USER_ROWS = 'user_rows'
|
|
22
|
+
# PARAMSET_USER_ROW_FIRST = 'user_row_first'
|
|
23
|
+
# PARAMSET_USER_ROW_LAST = 'user_row_last'
|
|
24
|
+
# PARAMSET_USER_ROW_SUBSAMP = 'row_subsampling'
|
|
26
25
|
PARAMSET_USER_SUBSAMP = 'user_subsampling'
|
|
27
26
|
|
|
27
|
+
PARAMSET_POLAR_EN = 'enable_dual_polar'
|
|
28
|
+
PARAMSET_DOPPLER_EN = 'enable_doppler'
|
|
29
|
+
|
|
28
30
|
PARAMSET_BS2BS = 'enable_BS2BS'
|
|
29
31
|
PARAMSET_FDTD = 'OFDM_channels' # TD/OFDM
|
|
30
32
|
|
|
31
33
|
PARAMSET_OFDM = 'OFDM'
|
|
32
34
|
PARAMSET_OFDM_SC_NUM = 'subcarriers'
|
|
33
|
-
PARAMSET_OFDM_SC_LIM = 'subcarriers_limit'
|
|
34
|
-
PARAMSET_OFDM_SC_SAMP = '
|
|
35
|
+
# PARAMSET_OFDM_SC_LIM = 'subcarriers_limit'
|
|
36
|
+
PARAMSET_OFDM_SC_SAMP = 'selected_subcarriers'
|
|
35
37
|
PARAMSET_OFDM_BW = 'bandwidth'
|
|
36
38
|
PARAMSET_OFDM_BW_MULT = 1e9 # Bandwidth input is GHz, multiply by this
|
|
37
39
|
PARAMSET_OFDM_LPF = 'RX_filter'
|
|
@@ -42,7 +44,8 @@ PARAMSET_ANT_SHAPE = 'shape'
|
|
|
42
44
|
PARAMSET_ANT_SPACING = 'spacing'
|
|
43
45
|
PARAMSET_ANT_ROTATION = 'rotation'
|
|
44
46
|
PARAMSET_ANT_RAD_PAT = 'radiation_pattern'
|
|
45
|
-
PARAMSET_ANT_RAD_PAT_VALS = ['isotropic', 'halfwave-dipole']
|
|
47
|
+
PARAMSET_ANT_RAD_PAT_VALS = ['isotropic', 'halfwave-dipole']
|
|
48
|
+
PARAMSET_ANT_FOV = 'FoV'
|
|
46
49
|
|
|
47
50
|
# INNER VARIABLES
|
|
48
51
|
PARAMSET_ACTIVE_UE = 'active_UE'
|
|
@@ -56,7 +59,10 @@ PARAMSET_SCENARIO_PARAMS_CF = 'carrier_freq'
|
|
|
56
59
|
PARAMSET_SCENARIO_PARAMS_TX_POW = 'tx_power'
|
|
57
60
|
PARAMSET_SCENARIO_PARAMS_NUM_BS = 'num_BS'
|
|
58
61
|
PARAMSET_SCENARIO_PARAMS_USER_GRIDS = 'user_grids'
|
|
62
|
+
PARAMSET_SCENARIO_PARAMS_POLAR_EN = 'dual_polar_available'
|
|
63
|
+
PARAMSET_SCENARIO_PARAMS_DOPPLER_EN = 'doppler_available'
|
|
59
64
|
|
|
65
|
+
PARAMSET_SCENARIO_PARAMS_PATH = 'scenario_params_path'
|
|
60
66
|
# OUTPUT VARIABLES
|
|
61
67
|
OUT_CHANNEL = 'channel'
|
|
62
68
|
OUT_PATH = 'paths'
|
|
@@ -73,6 +79,9 @@ OUT_PATH_DOA_THETA = 'DoA_theta'
|
|
|
73
79
|
OUT_PATH_PHASE = 'phase'
|
|
74
80
|
OUT_PATH_TOA = 'ToA'
|
|
75
81
|
OUT_PATH_RX_POW = 'power'
|
|
82
|
+
OUT_PATH_LOS = 'LoS'
|
|
83
|
+
OUT_PATH_DOP_VEL = 'Doppler_vel'
|
|
84
|
+
OUT_PATH_DOP_ACC = 'Doppler_acc'
|
|
76
85
|
OUT_PATH_ACTIVE = 'active_paths'
|
|
77
86
|
|
|
78
87
|
# FILE LISTS - raytracing.load_ray_data()
|
|
@@ -90,3 +99,8 @@ LOAD_FILE_SP_CF = 'carrier_freq'
|
|
|
90
99
|
LOAD_FILE_SP_TX_POW = 'transmit_power'
|
|
91
100
|
LOAD_FILE_SP_NUM_BS = 'num_BS'
|
|
92
101
|
LOAD_FILE_SP_USER_GRIDS = 'user_grids'
|
|
102
|
+
LOAD_FILE_SP_DOPPLER = 'doppler_available'
|
|
103
|
+
LOAD_FILE_SP_POLAR = 'dual_polar_available'
|
|
104
|
+
|
|
105
|
+
# Constants
|
|
106
|
+
LIGHTSPEED = 299792458
|