项目

一般

简介

【技术分享】phy抓数分析工具-支持显示RSRP » 画数据信道的频域图1_4.py

phy抓数分析工具 - 吕 国荣, 2023-10-10 19:12

 
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
    
    (1-1/1)