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.
Files changed (27) hide show
  1. {deepmimo-2.0 → deepmimo-3.2.9}/PKG-INFO +9 -4
  2. {deepmimo-2.0 → deepmimo-3.2.9}/README.md +10 -0
  3. deepmimo-3.2.9/setup.py +36 -0
  4. {deepmimo-2.0 → deepmimo-3.2.9}/src/DeepMIMO.egg-info/PKG-INFO +9 -4
  5. deepmimo-3.2.9/src/DeepMIMO.egg-info/SOURCES.txt +19 -0
  6. {deepmimo-2.0 → deepmimo-3.2.9}/src/DeepMIMO.egg-info/requires.txt +1 -0
  7. deepmimo-3.2.9/src/DeepMIMO.egg-info/top_level.txt +1 -0
  8. deepmimo-3.2.9/src/DeepMIMOv3/__init__.py +4 -0
  9. {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/ant_patterns.py +1 -1
  10. {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/construct_deepmimo.py +102 -25
  11. {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/consts.py +23 -9
  12. {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/generator.py +120 -47
  13. {deepmimo-2.0/src/DeepMIMO → deepmimo-3.2.9/src/DeepMIMOv3}/params.py +13 -16
  14. deepmimo-2.0/src/DeepMIMO/raytracing.py → deepmimo-3.2.9/src/DeepMIMOv3/raytracing_v2.py +62 -38
  15. deepmimo-3.2.9/src/DeepMIMOv3/raytracing_v3.py +182 -0
  16. deepmimo-3.2.9/src/DeepMIMOv3/utils.py +292 -0
  17. deepmimo-3.2.9/src/DeepMIMOv3/visualization.py +259 -0
  18. deepmimo-2.0/setup.py +0 -30
  19. deepmimo-2.0/src/DeepMIMO/__init__.py +0 -4
  20. deepmimo-2.0/src/DeepMIMO/file_loaders.py +0 -59
  21. deepmimo-2.0/src/DeepMIMO/utils.py +0 -16
  22. deepmimo-2.0/src/DeepMIMO.egg-info/SOURCES.txt +0 -18
  23. deepmimo-2.0/src/DeepMIMO.egg-info/top_level.txt +0 -1
  24. {deepmimo-2.0 → deepmimo-3.2.9}/LICENSE.md +0 -0
  25. {deepmimo-2.0 → deepmimo-3.2.9}/setup.cfg +0 -0
  26. {deepmimo-2.0 → deepmimo-3.2.9}/src/DeepMIMO.egg-info/dependency_links.txt +0 -0
  27. {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.0
4
- Summary: DeepMIMO
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 :: 4 - Beta
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
- DeepMIMOv2 dataset generator library
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
 
@@ -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.0
4
- Summary: DeepMIMO
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 :: 4 - Beta
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
- DeepMIMOv2 dataset generator library
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
@@ -1,3 +1,4 @@
1
1
  numpy
2
2
  scipy
3
3
  tqdm
4
+ matplotlib
@@ -0,0 +1 @@
1
+ DeepMIMOv3
@@ -0,0 +1,4 @@
1
+ from DeepMIMOv3.generator import generate_data
2
+ from DeepMIMOv3.params import default_params
3
+ from DeepMIMOv3.construct_deepmimo import ant_indices, array_response
4
+ from DeepMIMOv3.sionna_adapter import DeepMIMOSionnaAdapter
@@ -8,7 +8,7 @@ Authors: Umut Demirhan, Ahmed Alkhateeb
8
8
  Date: 3/16/2022
9
9
  """
10
10
 
11
- import DeepMIMO.consts as c
11
+ import DeepMIMOv3.consts as c
12
12
  import numpy as np
13
13
 
14
14
  class AntennaPattern():
@@ -8,11 +8,10 @@ Authors: Umut Demirhan, Ahmed Alkhateeb
8
8
  Date: 12/10/2021
9
9
  """
10
10
 
11
- import DeepMIMO.consts as c
11
+ import DeepMIMOv3.consts as c
12
12
  import numpy as np
13
13
  from tqdm import tqdm
14
- import types
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 = np.arange(0, params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_SC_LIM], params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_SC_SAMP])
26
- path_gen = OFDM_PathGenerator(params[c.PARAMSET_OFDM], subcarriers)
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(power.reshape(-1, 1),
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 = np.arange(0, params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_SC_LIM], params[c.PARAMSET_OFDM][c.PARAMSET_OFDM_SC_SAMP])
95
- path_gen = OFDM_PathGenerator(params[c.PARAMSET_OFDM], subcarriers)
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(power.reshape(-1, 1),
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(panel_size[0]), panel_size[1]*panel_size[2])
171
- gamma_y = np.tile(np.repeat(np.arange(panel_size[1]), panel_size[0]), panel_size[2])
172
- gamma_z = np.repeat(np.arange(panel_size[2]), panel_size[0]*panel_size[1])
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, OFDM_params, subcarriers):
203
- self.OFDM_params = OFDM_params
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, power, delay_n, phase):
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
- return np.sqrt(power/self.total_subcarriers) * np.exp(1j*(np.deg2rad(phase) - (2*np.pi/self.total_subcarriers)*np.outer(delay_n, self.subcarriers) ))
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, power, delay_n, phase):
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
- PARAMSET_DYNAMIC = 'dynamic_settings'
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
- PARAMSET_USER_ROW_FIRST = 'user_row_first'
24
- PARAMSET_USER_ROW_LAST = 'user_row_last'
25
- PARAMSET_USER_ROW_SUBSAMP = 'row_subsampling'
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 = 'subcarriers_sampling'
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