1
|
"""
|
2
|
File: 分析频域数据的幅度信号.py
|
3
|
Author: lv.GR
|
4
|
Date created: 2023-09-12
|
5
|
Last modified: 2023.10.08 --1.4
|
6
|
Description:
|
7
|
1 安装python3
|
8
|
2 在windows 的cmd 窗口安装(管理员权限安装):
|
9
|
pip3 install numpy
|
10
|
pip3 install matplotlib
|
11
|
3 安装完成后,直接执行脚本即可;
|
12
|
Version: 1.2
|
13
|
"""
|
14
|
|
15
|
import numpy as np
|
16
|
import matplotlib.pyplot as plt
|
17
|
import tkinter as tk
|
18
|
from tkinter import filedialog
|
19
|
|
20
|
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用中文字体
|
21
|
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
|
22
|
|
23
|
|
24
|
# 创建一个tkinter窗口
|
25
|
root = tk.Tk()
|
26
|
root.withdraw() # 隐藏主窗口,只显示文件对话框
|
27
|
|
28
|
# 打开文件对话框,选择原始数据文件
|
29
|
file_path = filedialog.askopenfilename(title="选择频域数据文件", filetypes=[("Binary Files", "*.bin"), ("All Files", "*.*")])
|
30
|
|
31
|
if not file_path:
|
32
|
print("未选择文件。程序结束。")
|
33
|
else:
|
34
|
# 读取选定的文件中的IQ数据
|
35
|
with open(file_path, 'rb') as file:
|
36
|
raw_data = file.read()
|
37
|
|
38
|
# 解析二进制数据并进行幅度图绘制
|
39
|
# 1 -- len(raw_data) 计算 raw_data 的字节长度,即其中包含的字节数,然后将字节的长度除以4,计算出样点数
|
40
|
data_length = len(raw_data) // 4
|
41
|
print("输入的频域数据长度:", data_length)
|
42
|
|
43
|
# 2 -- 数据重构,生成(I,Q)的二维数组
|
44
|
# dtype=np.int16 指定数据的类型是16位有符号整数
|
45
|
# reshape函数将其重新构,每行包含两个16位整数,一个用于I(实部),一个用于Q(虚部),
|
46
|
# 将其重塑为一个形状为(data_length, 2)的二维数组
|
47
|
iq_data = np.frombuffer(raw_data, dtype=np.int16).reshape((data_length, 2))
|
48
|
|
49
|
# 频域数据的保存格式是(Q, I), 交换 I 和 Q 列
|
50
|
# 创建一个新的数组以存储交换后的数据
|
51
|
swapped_iq_data = np.empty_like(iq_data)
|
52
|
|
53
|
# 交换 I 和 Q 列
|
54
|
swapped_iq_data[:, 0] = iq_data[:, 1]
|
55
|
swapped_iq_data[:, 1] = iq_data[:, 0]
|
56
|
|
57
|
# 3 -- 计算每个样点的幅度值
|
58
|
amplitude = np.abs(swapped_iq_data[:, 0] + 1j * swapped_iq_data[:, 1]) # np.sqrt(a**2 + b**2)
|
59
|
amp_dBm = 10 * np.log10(amplitude**2 / (2 * 32767 ** 2)) - 40 # 注意amplitude 取值为0时 异常
|
60
|
sampling_rate = 1 # 122.88e6
|
61
|
|
62
|
# 4 -- 生成横轴的坐标
|
63
|
# np.arange() 是NumPy库中的函数,创建等差数列,生成横轴坐标;
|
64
|
# 如果 data_length 的值是100,那么这个数组将包含0到99的整数
|
65
|
time = np.arange(data_length) / sampling_rate
|
66
|
|
67
|
# 创建一个包含两个子图的画布
|
68
|
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(16, 8))
|
69
|
|
70
|
# 设置X轴刻度标签
|
71
|
x_labels = ['sym0', 'sym1', 'sym2', 'sym3', 'sym4', 'sym5', 'sym6', 'sym7', 'sym8', 'sym9', 'sym10', 'sym11', 'sym12', 'sym13']
|
72
|
x_labels_2ant = ['sym0', 'sym1', 'sym2', 'sym3', 'sym4', 'sym5', 'sym6', 'sym7', 'sym8', 'sym9', 'sym10', 'sym11', 'sym12', 'sym13',
|
73
|
'sym0', 'sym1', 'sym2', 'sym3', 'sym4', 'sym5', 'sym6', 'sym7', 'sym8', 'sym9', 'sym10', 'sym11', 'sym12', 'sym13']
|
74
|
|
75
|
# 5 --画plot1,根据数据的长度,调整图的大小和横轴的刻度值
|
76
|
if data_length == 3276 * 14: #45864
|
77
|
# plt.figure(figsize=(14, 6))
|
78
|
ax1.plot(time, amplitude, linewidth=1, color='b') # 'b' 蓝色; 'y'-黄色 'r'-红色
|
79
|
x_ticks = np.arange(0, data_length, 3276) # 设置横轴刻度,在1到3276*14的范围内,每3276设置一个刻度
|
80
|
ax1.set_xticks(x_ticks)
|
81
|
|
82
|
# 添加刻度区间标签
|
83
|
for i, tick in enumerate(x_ticks):
|
84
|
ax1.text(tick, -0.08, x_labels[i], fontsize=12, ha='left', va='top') # 水平对齐和顶部对齐
|
85
|
|
86
|
elif data_length == 3276 * 28:
|
87
|
#plt.figure(figsize=(16, 6))
|
88
|
ax1.plot(time, amplitude, color='b')
|
89
|
x_ticks = np.arange(0, data_length, 3276) # 设置横轴刻度,在1到3276*14的范围内,每3276设置一个刻度
|
90
|
ax1.set_xticks(x_ticks)
|
91
|
|
92
|
# 添加刻度区间标签
|
93
|
for i, tick in enumerate(x_ticks):
|
94
|
ax1.text(tick, -0.08, x_labels_2ant[i], fontsize=12, ha='left',va='top') # 水平对齐和顶部对齐
|
95
|
|
96
|
# 6 -- 画图
|
97
|
ax1.set_xlabel('样点(子载波位置)')
|
98
|
ax1.set_ylabel('幅值Amp')
|
99
|
ax1.set_title('频域数据信号幅度-图1')
|
100
|
ax1.grid(True)
|
101
|
|
102
|
# 第二个图,与第一个图相同,但修改纵轴刻度
|
103
|
if data_length == 3276 * 14: #45864
|
104
|
ax2.plot(time, amp_dBm, linewidth=1, color='b') # 'b' 蓝色; 'y'-黄色 'r'-红色
|
105
|
x_ticks = np.arange(0, data_length, 3276) # 设置横轴刻度,在1到3276*14的范围内,每3276设置一个刻度
|
106
|
ax2.set_xticks(x_ticks)
|
107
|
|
108
|
elif data_length == 3276 * 28:
|
109
|
ax2.plot(time, amp_dBm, color='b')
|
110
|
x_ticks = np.arange(0, data_length, 3276) # 设置横轴刻度,在1到3276*14的范围内,每3276设置一个刻度
|
111
|
ax2.set_xticks(x_ticks)
|
112
|
|
113
|
max_dbm_value = -40 # 最大值
|
114
|
ax2.axhline(y=max_dbm_value, color='r', linestyle='--', label=f'功率溢出线: ({max_dbm_value} dBm)')
|
115
|
ax2.legend() # 添加图例
|
116
|
ax2.set_xlabel('样点(子载波位置)')
|
117
|
ax2.set_ylabel('RSRP-dBm')
|
118
|
ax2.set_title('频域数据RSRP(值)dBm-图2')
|
119
|
ax2.grid(True)
|
120
|
plt.tight_layout() # 调整子图之间的间距
|
121
|
plt.show() # 显示画布
|
122
|
|