bcg_quality_label/bcg_quality_label.py

1171 lines
62 KiB
Python
Raw Permalink Normal View History

2025-02-14 16:29:13 +08:00
"""
@author:Yosa
@file:bcg_quality_label.py
@email:2023025086@m.scnu.edu.cn
@time:2025/2/11
"""
import sys
from logging import NOTSET, getLogger, FileHandler, Formatter, StreamHandler, info, error, debug
from time import time, strftime, localtime
import numpy as np
2025-02-21 20:41:16 +08:00
from pandas import DataFrame, read_csv
2025-02-14 16:29:13 +08:00
from matplotlib.ticker import FuncFormatter
2025-02-21 20:41:16 +08:00
from numpy import nan
2025-02-14 16:29:13 +08:00
from matplotlib import use
2025-02-21 20:41:16 +08:00
from matplotlib import pyplot as plt
2025-02-14 16:29:13 +08:00
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT
from datetime import datetime
from pathlib import Path
2025-02-21 20:41:16 +08:00
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QMessageBox, QButtonGroup, QApplication, QTableWidgetItem, QTableWidget
2025-02-14 16:29:13 +08:00
from scipy import signal
from MainWindow import Ui_MainWindow
use("Qt5Agg") # 声明使用 QT5
# 设置日志
logger = getLogger()
logger.setLevel(NOTSET)
realtime = strftime('%Y%m%d', localtime(time()))
if not Path("logs").exists():
Path("logs").mkdir(exist_ok=True)
fh = FileHandler(Path("logs") / (realtime + ".log"), mode='a')
fh.setLevel(NOTSET)
fh.setFormatter(Formatter("%(asctime)s: %(message)s"))
logger.addHandler(fh)
ch = StreamHandler()
ch.setLevel(NOTSET)
ch.setFormatter(Formatter("%(asctime)s: %(message)s"))
logger.addHandler(ch)
getLogger('matplotlib.font_manager').disabled = True
info("------------------------------------")
info("--------bcg_quality_label.py--------")
class MainWindow(QMainWindow, Ui_MainWindow):
# 全局变量初始化
data = np.array([])
data = data.astype(np.float64)
artifact = np.array([])
artifact = artifact.astype(np.int64)
last_data_idx = -1
current_data_idx = 0
data_part_num = 0
current_part_num = 1
artifact_number = np.array([])
artifact_number = artifact_number.astype(np.int64)
artifact_type = np.array([])
artifact_type = artifact_type.astype(np.int64)
artifact_mask = np.array([])
artifact_mask = artifact_mask.astype(np.int64)
longest_continuous_time = 0
artifact_time_percentage = 0
label = np.array([])
label = label.astype(np.str_)
# 程序初始化操作
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
# 设置画框
self.figure = plt.figure(figsize=(12, 6), dpi=150)
self.ax0 = self.figure.add_subplot(111)
self.ax0.xaxis.set_major_formatter(FuncFormatter(lambda x, p: f"{x:.0f}"))
self.canvas = FigureCanvasQTAgg(self.figure)
self.figToolbar = NavigationToolbar2QT(self.canvas)
self.verticalLayout_canvas.addWidget(self.canvas)
self.verticalLayout_canvas.addWidget(self.figToolbar)
# 画框子图初始化
plt.margins(0, 0)
plt.tight_layout()
# 界面状态初始化
self.radioButton_inputMode_auto.setChecked(True)
self.lineEdit_rootpath.setEnabled(False)
self.lineEdit_datapath.setEnabled(False)
self.lineEdit_artifactpath.setEnabled(False)
self.lineEdit_savepath.setEnabled(False)
self.lineEdit_current_part_time.setEnabled(False)
self.lineEdit_data_part_num.setEnabled(False)
self.lineEdit_longest_continuous_time.setEnabled(False)
self.lineEdit_artifact_time_percentage.setEnabled(False)
self.pushButton_datapath_open.setEnabled(False)
self.pushButton_artifactpath_open.setEnabled(False)
self.pushButton_savepath_open.setEnabled(False)
self.groupBox_artifact_type.setEnabled(False)
self.groupBox_status.setEnabled(False)
self.groupBox_function.setEnabled(False)
self.groupBox_operation.setEnabled(False)
self.groupBox_labelDisplay_10s.setVisible(False)
self.groupBox_labelDisplay_30s.setVisible(False)
self.checkBox_highlight_longest_continuous.setChecked(True)
# 初始化按钮快捷键
self.pushButton_left.setShortcut(QCoreApplication.translate("MainWindow", "A"))
self.pushButton_right.setShortcut(QCoreApplication.translate("MainWindow", "D"))
# 设置表格属性
self.tableWidget_label10s_a.setHorizontalHeaderLabels(['a'])
self.tableWidget_label10s_b.setHorizontalHeaderLabels(['b'])
self.tableWidget_label10s_c.setHorizontalHeaderLabels(['c'])
self.tableWidget_label10s_tobeLabeled.setHorizontalHeaderLabels(['未打标'])
self.tableWidget_label30s_a1.setHorizontalHeaderLabels(['a1'])
self.tableWidget_label30s_a2.setHorizontalHeaderLabels(['a2'])
self.tableWidget_label30s_b1.setHorizontalHeaderLabels(['b1'])
self.tableWidget_label30s_b2.setHorizontalHeaderLabels(['b2'])
self.tableWidget_label30s_c.setHorizontalHeaderLabels(['c'])
self.tableWidget_label30s_tobeLabeled.setHorizontalHeaderLabels(['未打标'])
self.tableWidget_label10s_a.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label10s_b.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label10s_c.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label10s_tobeLabeled.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label30s_a1.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label30s_a2.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label30s_b1.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label30s_b2.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label30s_c.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label30s_tobeLabeled.setEditTriggers(QTableWidget.NoEditTriggers)
self.tableWidget_label10s_a.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label10s_a.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label10s_b.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label10s_b.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label10s_c.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label10s_c.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label10s_tobeLabeled.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label10s_tobeLabeled.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label30s_a1.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label30s_a1.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label30s_a2.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label30s_a2.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label30s_b1.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label30s_b1.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label30s_b2.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label30s_b2.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label30s_c.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label30s_c.horizontalHeader().setSectionResizeMode(1)
self.tableWidget_label30s_tobeLabeled.horizontalHeader().setStretchLastSection(True)
self.tableWidget_label30s_tobeLabeled.horizontalHeader().setSectionResizeMode(1)
# 单选框组件分组
self.buttonGroup_displayMode = QButtonGroup()
self.buttonGroup_displayMode.addButton(self.radioButton_10s_mode)
self.buttonGroup_displayMode.addButton(self.radioButton_30s_mode)
# 槽函数连接控件初始化
self.pushButton_rootpath_open.clicked.connect(self.slot_btn_selectPath)
self.pushButton_datapath_open.clicked.connect(self.slot_btn_selectPath)
self.pushButton_artifactpath_open.clicked.connect(self.slot_btn_selectPath)
self.pushButton_savepath_open.clicked.connect(self.slot_btn_selectPath)
self.pushButton_dataInput.clicked.connect(self.slot_btn_dataInput)
self.radioButton_inputMode_auto.clicked.connect(self.slot_radioBtn_inputMode_auto)
self.radioButton_inputMode_manual.clicked.connect(self.slot_radioBtn_inputMode_manual)
self.checkBox_allin.clicked.connect(self.slot_checkBox_allin)
self.checkBox_type1.clicked.connect(self.slot_checkBox_type1)
self.checkBox_type2.clicked.connect(self.slot_checkBox_type2)
self.checkBox_type3.clicked.connect(self.slot_checkBox_type3)
self.checkBox_type4.clicked.connect(self.slot_checkBox_type4)
self.checkBox_type5.clicked.connect(self.slot_checkBox_type5)
self.pushButton_left.clicked.connect(self.slot_btn_left)
self.pushButton_right.clicked.connect(self.slot_btn_right)
self.pushButton_label10s_a.clicked.connect(self.slot_btn_label)
self.pushButton_label10s_b.clicked.connect(self.slot_btn_label)
self.pushButton_label10s_c.clicked.connect(self.slot_btn_label)
self.pushButton_label10s_f.clicked.connect(self.slot_btn_label)
self.pushButton_label30s_a1.clicked.connect(self.slot_btn_label)
self.pushButton_label30s_a2.clicked.connect(self.slot_btn_label)
self.pushButton_label30s_b1.clicked.connect(self.slot_btn_label)
self.pushButton_label30s_b2.clicked.connect(self.slot_btn_label)
self.pushButton_label30s_c.clicked.connect(self.slot_btn_label)
self.pushButton_label30s_f.clicked.connect(self.slot_btn_label)
self.pushButton_invalid_signal_label.clicked.connect(self.slot_btn_invalid_signal_label)
self.pushButton_Ctype_signal_label.clicked.connect(self.slot_btn_Ctype_signal_label)
self.checkBox_highlight_longest_continuous.clicked.connect(self.slot_checkBox_highlight_longest_continuous)
self.checkBox_display_afterfilter.clicked.connect(self.slot_checkBox_display_afterfilter)
self.checkBox_examine_tobeLabeled.clicked.connect(self.slot_checkBox_examine_tobeLabeled)
self.tableWidget_label10s_a.cellDoubleClicked.connect(self.slot_tableWidget_label10s_a_on_cell_double_clicked)
self.tableWidget_label10s_b.cellDoubleClicked.connect(self.slot_tableWidget_label10s_b_on_cell_double_clicked)
self.tableWidget_label10s_c.cellDoubleClicked.connect(self.slot_tableWidget_label10s_c_on_cell_double_clicked)
self.tableWidget_label10s_tobeLabeled.cellDoubleClicked.connect(self.slot_tableWidget_label10s_tobeLabeled_on_cell_double_clicked)
self.tableWidget_label30s_a1.cellDoubleClicked.connect(self.slot_tableWidget_label30s_a1_on_cell_double_clicked)
self.tableWidget_label30s_a2.cellDoubleClicked.connect(self.slot_tableWidget_label30s_a2_on_cell_double_clicked)
self.tableWidget_label30s_b1.cellDoubleClicked.connect(self.slot_tableWidget_label30s_b1_on_cell_double_clicked)
self.tableWidget_label30s_b2.cellDoubleClicked.connect(self.slot_tableWidget_label30s_b2_on_cell_double_clicked)
self.tableWidget_label30s_c.cellDoubleClicked.connect(self.slot_tableWidget_label30s_c_on_cell_double_clicked)
self.tableWidget_label30s_tobeLabeled.cellDoubleClicked.connect(self.slot_tableWidget_label30s_tobeLabeled_on_cell_double_clicked)
# 消息弹窗初始化
self.msgBox = QMessageBox()
self.msgBox.setWindowTitle("消息")
def slot_btn_selectPath(self):
fileDialog = QFileDialog()
if self.sender() == self.pushButton_rootpath_open:
fileDialog.setFileMode(QFileDialog.Directory)
fileDialog.setOption(QFileDialog.ShowDirsOnly, True)
if fileDialog.exec_() == QFileDialog.Accepted:
file_path = fileDialog.selectedFiles()[0]
if not file_path:
error("Root Path not Exist...")
self.textBrowser_update("操作:根目录路径输入错误")
self.msgBox.setText("根目录路径输入错误")
self.msgBox.setIcon(QMessageBox.Critical)
self.msgBox.exec()
return
self.lineEdit_rootpath.setText(file_path)
file_path = Path(file_path)
info("Loading Root Path...")
self.data_and_artifact_Path = file_path / "Align"
data_path = self.data_and_artifact_Path / "BCG_sync.txt"
artifact_path = self.data_and_artifact_Path / "Artifact_a.txt"
# 检查路径下的BCG_sync.txt和Artifact_a.txt文件是否存在
if self.data_and_artifact_Path.exists() and data_path.exists() and artifact_path.exists():
# 更新数据路径文本框
self.lineEdit_datapath.setText(str(data_path))
self.lineEdit_artifactpath.setText(str(artifact_path))
self.lineEdit_savepath.setText(str(self.data_and_artifact_Path))
info("Successfully Loaded Root Path.")
self.textBrowser_update("操作:根目录路径选择成功")
else:
info("Failed to Load Root Path.")
self.textBrowser_update("操作:根目录路径选择错误,缺乏必要数据文件")
self.msgBox.setText("根目录路径选择错误,缺乏必要数据文件")
self.msgBox.setIcon(QMessageBox.Critical)
self.msgBox.exec()
return
else:
info("Canceled Loading Root Path.")
self.textBrowser_update("提示:根目录路径选择取消")
self.msgBox.setText("根目录路径选择取消")
self.msgBox.setIcon(QMessageBox.Warning)
self.msgBox.exec()
elif self.sender() == self.pushButton_savepath_open:
fileDialog.setFileMode(QFileDialog.Directory)
fileDialog.setOption(QFileDialog.ShowDirsOnly, True)
if fileDialog.exec_() == QFileDialog.Accepted:
file_path = fileDialog.selectedFiles()[0]
self.lineEdit_savepath.setText(str(Path(file_path)))
info("Successfully Loaded Save Path.")
self.textBrowser_update("操作:保存路径选择成功")
else:
info("Canceled Loading Save Path.")
self.textBrowser_update("提示:保存路径选择取消")
self.msgBox.setText("保存路径选择取消")
self.msgBox.setIcon(QMessageBox.Warning)
self.msgBox.exec()
else:
fileDialog.setFileMode(QFileDialog.ExistingFile)
fileDialog.setOption(QFileDialog.ReadOnly, True)
fileDialog.setNameFilter("Text Files (*.txt)")
if fileDialog.exec_() == QFileDialog.Accepted:
file_path = fileDialog.selectedFiles()[0]
if self.sender() == self.pushButton_datapath_open:
self.lineEdit_datapath.setText(file_path)
elif self.sender() == self.pushButton_artifactpath_open:
self.lineEdit_artifactpath.setText(file_path)
info("Successfully Loaded Data Path.")
self.textBrowser_update("操作:数据路径选择成功")
else:
info("Canceled Loading Data Path.")
self.textBrowser_update("提示:数据路径选择取消")
self.msgBox.setText("数据路径选择取消")
self.msgBox.setIcon(QMessageBox.Warning)
self.msgBox.exec()
def slot_btn_dataInput(self):
if (self.lineEdit_datapath.text() != "" or self.lineEdit_artifactpath.text() != "" or self.lineEdit_savepath.text() != "") and (self.radioButton_30s_mode.isChecked() == True or self.radioButton_10s_mode.isChecked() == True):
info("Inputing Data...")
self.textBrowser_update("提示:开始导入数据")
# 导入数据
self.artifact = np.array([])
file = open(str(self.lineEdit_datapath.text()), 'r')
self.data = file.readlines()
self.data = list(map(float, self.data))
self.data_without_industrialFrequencyNoise = self.wipe_industrialFrequencyNoise(self.data, 1000)
file = open(str(self.lineEdit_artifactpath.text()), 'r')
self.artifact = np.array(file.readlines())
self.data = np.array(self.data)
self.data = self.data.astype(np.float64)
self.data_without_industrialFrequencyNoise = np.array([self.data_without_industrialFrequencyNoise])
self.data_without_industrialFrequencyNoise = self.data_without_industrialFrequencyNoise.astype(np.float64)[0]
self.artifact = self.artifact.astype(np.int64)
# 获取信号的段数,检查数据长度正确性
if self.radioButton_10s_mode.isChecked():
self.data_part_num = len(self.data) // 10000
self.groupBox_labelDisplay_10s.setVisible(True)
2025-02-14 16:43:35 +08:00
self.lineEdit_savepath.setText(str(Path(self.lineEdit_savepath.text()) / "SQ_label_10s.csv"))
2025-02-14 16:29:13 +08:00
elif self.radioButton_30s_mode.isChecked():
self.data_part_num = len(self.data) // 30000
self.groupBox_labelDisplay_30s.setVisible(True)
2025-02-14 16:43:35 +08:00
self.lineEdit_savepath.setText(str(Path(self.lineEdit_savepath.text()) / "SQ_label_30s.csv"))
2025-02-14 16:29:13 +08:00
if self.data_part_num == 0:
info("Failed to Input Data!")
self.textBrowser_update("操作:导入数据失败,请检查数据长度")
self.msgBox.setText("导入失败,请检查数据长度")
self.msgBox.setIcon(QMessageBox.Critical)
self.msgBox.exec()
return
# 检查体动标签正确性
if len(self.artifact) % 4 == 0:
for i in range(1, len(self.artifact), 4):
if self.artifact[i] not in [1, 2, 3, 4, 5]:
info(f"Failed to Input Artifact! Error in Artifact[{i}] not in [1, 2, 3, 4, 5].")
self.textBrowser_update("操作:导入体动失败,请检查体动标签格式")
self.msgBox.setText("导入失败,请检查体动标签格式")
self.msgBox.setIcon(QMessageBox.Critical)
self.msgBox.exec()
return
else:
info("Failed to Input Artifact!")
self.textBrowser_update("操作导入体动失败请检查体动长度是否为4的倍数")
self.msgBox.setText("导入失败请检查体动长度是否为4的倍数")
self.msgBox.setIcon(QMessageBox.Critical)
self.msgBox.exec()
return
# 定义绘制体动所需要的数组
artifact_start = np.array([])
artifact_start = artifact_start.astype(np.int64)
artifact_end = np.array([])
artifact_end = artifact_end.astype(np.int64)
for i in range(0, len(self.artifact), 4):
self.artifact_number = np.append(self.artifact_number, self.artifact[i])
for i in range(1, len(self.artifact), 4):
self.artifact_type = np.append(self.artifact_type, self.artifact[i])
for i in range(2, len(self.artifact), 4):
artifact_start = np.append(artifact_start, self.artifact[i])
for i in range(3, len(self.artifact), 4):
artifact_end = np.append(artifact_end, self.artifact[i])
self.artifact_mask = np.zeros(len(self.data))
for i in range(0, len(self.artifact_number)):
if self.artifact_type[i] == 1:
self.artifact_mask[artifact_start[i]: artifact_end[i] + 1] = 1
elif self.artifact_type[i] == 2:
self.artifact_mask[artifact_start[i]: artifact_end[i] + 1] = 2
elif self.artifact_type[i] == 3:
self.artifact_mask[artifact_start[i]: artifact_end[i] + 1] = 3
elif self.artifact_type[i] == 4:
self.artifact_mask[artifact_start[i]: artifact_end[i] + 1] = 4
elif self.artifact_type[i] == 5:
self.artifact_mask[artifact_start[i]: artifact_end[i] + 1] = 5
# 尝试获取之前打标的存档,若不存在存档,则创建新存档
if self.radioButton_10s_mode.isChecked() == True:
self.pushButton_Ctype_signal_label.setEnabled(True)
elif self.radioButton_30s_mode.isChecked() == True:
self.pushButton_Ctype_signal_label.setEnabled(False)
2025-02-14 16:43:35 +08:00
if not Path(self.lineEdit_savepath.text()).exists():
2025-02-14 16:49:32 +08:00
info("Not Found History Archive csv File, Made new csv File.")
self.textBrowser_update("提示未找到历史存档csv文件创建新的csv文件")
2025-02-14 16:43:35 +08:00
self.label = np.full(self.data_part_num, "f")
self.df_label = DataFrame(columns=["label", "remark"])
self.df_label["label"] = self.label
self.df_label["remark"] = ""
self.df_label["label"] = self.df_label["label"].astype(str)
self.df_label["remark"] = self.df_label["remark"].astype(str)
else:
2025-02-14 16:49:32 +08:00
info("Found History Archive csv File, Loaded History Archive csv File.")
self.textBrowser_update("提示找到历史存档csv文件载入历史存档csv文件")
2025-02-14 16:43:35 +08:00
self.df_label = read_csv(self.lineEdit_savepath.text(), encoding="gbk")
self.label = self.df_label["label"].astype(str)
self.df_label.to_csv(self.lineEdit_savepath.text(), index=False, encoding="gbk")
self.lineEdit_savepath.setText(str(self.lineEdit_savepath.text()))
2025-02-14 16:29:13 +08:00
# 界面状态更新
self.groupBox_inputSetting.setEnabled(False)
self.groupBox_artifact_type.setEnabled(True)
self.groupBox_status.setEnabled(True)
self.groupBox_function.setEnabled(True)
self.groupBox_operation.setEnabled(True)
MainWindow.setWindowTitle(self, QCoreApplication.translate("MainWindow",
"BCG_Quality_Label - Data Path: " + self.lineEdit_rootpath.text()))
self.update_status()
self.plot_data_and_artifact()
self.update_tableWidget()
info("Finished Input Data.")
self.textBrowser_update("提示:导入数据完成")
elif self.radioButton_30s_mode.isChecked() == False and self.radioButton_10s_mode.isChecked() == False:
info("Failed to Input Data!")
self.textBrowser_update("操作:导入数据失败")
self.msgBox.setText("导入失败,请选择显示模式")
self.msgBox.setIcon(QMessageBox.Critical)
self.msgBox.exec()
else:
info("Failed to Input Data!")
self.textBrowser_update("操作:导入数据失败")
self.msgBox.setText("导入失败,请正确输入路径")
self.msgBox.setIcon(QMessageBox.Critical)
self.msgBox.exec()
def slot_radioBtn_inputMode_auto(self):
self.pushButton_rootpath_open.setEnabled(True)
self.pushButton_datapath_open.setEnabled(False)
self.pushButton_artifactpath_open.setEnabled(False)
self.pushButton_savepath_open.setEnabled(False)
def slot_radioBtn_inputMode_manual(self):
self.pushButton_rootpath_open.setEnabled(False)
self.pushButton_datapath_open.setEnabled(True)
self.pushButton_artifactpath_open.setEnabled(True)
self.pushButton_savepath_open.setEnabled(True)
def slot_btn_left(self):
if self.current_part_num == 1:
info(f"Viewing the First Part.")
self.msgBox.setText("你正在查看第1段信号")
self.msgBox.setIcon(QMessageBox.Information)
self.msgBox.exec()
else:
self.last_data_idx = self.current_data_idx
self.current_part_num -= 1
while self.checkBox_examine_tobeLabeled.isChecked() == True and self.df_label.at[self.current_part_num - 1, "label"] != "f":
self.current_part_num -= 1
if self.current_part_num == 0:
self.current_part_num = 1
info(f"All Parts of Left are Labeled, Jumped to the First Part.")
self.msgBox.setText("前面的片段都被打标将跳转至第1段信号")
self.msgBox.setIcon(QMessageBox.Information)
self.msgBox.exec()
break
if self.radioButton_10s_mode.isChecked() == True:
self.current_data_idx -= 10000
elif self.radioButton_30s_mode.isChecked() == True:
self.current_data_idx -= 30000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Viewing the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:上一段信号,第{self.current_part_num}")
def slot_btn_right(self):
if self.current_part_num == self.data_part_num:
info(f"Viewing the Last Part.")
self.msgBox.setText("你正在查看最后1段信号")
self.msgBox.setIcon(QMessageBox.Information)
self.msgBox.exec()
else:
self.last_data_idx = self.current_data_idx
self.current_part_num += 1
while self.checkBox_examine_tobeLabeled.isChecked() == True and self.df_label.at[self.current_part_num - 1, "label"] != "f":
self.current_part_num += 1
if self.current_part_num == self.data_part_num + 1:
self.current_part_num = self.data_part_num
info(f"All Parts of Right are Labeled, Jumped to the Last Part.")
self.msgBox.setText("后面的片段都被打标将跳转至最后1段信号")
self.msgBox.setIcon(QMessageBox.Information)
self.msgBox.exec()
break
if self.radioButton_10s_mode.isChecked() == True:
self.current_data_idx += 10000
elif self.radioButton_30s_mode.isChecked() == True:
self.current_data_idx += 30000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Viewing the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:下一段信号,第{self.current_part_num}")
def slot_checkBox_allin(self):
if self.checkBox_allin.isChecked() == True:
self.checkBox_type1.setChecked(True)
self.checkBox_type2.setChecked(True)
self.checkBox_type3.setChecked(True)
self.checkBox_type4.setChecked(True)
self.checkBox_type5.setChecked(True)
else:
self.checkBox_type1.setChecked(False)
self.checkBox_type2.setChecked(False)
self.checkBox_type3.setChecked(False)
self.checkBox_type4.setChecked(False)
self.checkBox_type5.setChecked(False)
self.plot_data_and_artifact()
def slot_checkBox_type1(self):
if self.checkBox_type1.isChecked() == False:
self.checkBox_allin.setChecked(False)
self.plot_data_and_artifact()
if self.checkBox_type1.isChecked() == True and self.checkBox_type2.isChecked() == True and self.checkBox_type3.isChecked() == True and self.checkBox_type4.isChecked() == True and self.checkBox_type5.isChecked() == True:
self.checkBox_allin.setChecked(True)
def slot_checkBox_type2(self):
if self.checkBox_type2.isChecked() == False:
self.checkBox_allin.setChecked(False)
self.plot_data_and_artifact()
if self.checkBox_type1.isChecked() == True and self.checkBox_type2.isChecked() == True and self.checkBox_type3.isChecked() == True and self.checkBox_type4.isChecked() == True and self.checkBox_type5.isChecked() == True:
self.checkBox_allin.setChecked(True)
def slot_checkBox_type3(self):
if self.checkBox_type3.isChecked() == False:
self.checkBox_allin.setChecked(False)
self.plot_data_and_artifact()
if self.checkBox_type1.isChecked() == True and self.checkBox_type2.isChecked() == True and self.checkBox_type3.isChecked() == True and self.checkBox_type4.isChecked() == True and self.checkBox_type5.isChecked() == True:
self.checkBox_allin.setChecked(True)
def slot_checkBox_type4(self):
if self.checkBox_type4.isChecked() == False:
self.checkBox_allin.setChecked(False)
self.plot_data_and_artifact()
if self.checkBox_type1.isChecked() == True and self.checkBox_type2.isChecked() == True and self.checkBox_type3.isChecked() == True and self.checkBox_type4.isChecked() == True and self.checkBox_type5.isChecked() == True:
self.checkBox_allin.setChecked(True)
def slot_checkBox_type5(self):
if self.checkBox_type5.isChecked() == False:
self.checkBox_allin.setChecked(False)
self.plot_data_and_artifact()
if self.checkBox_type1.isChecked() == True and self.checkBox_type2.isChecked() == True and self.checkBox_type3.isChecked() == True and self.checkBox_type4.isChecked() == True and self.checkBox_type5.isChecked() == True:
self.checkBox_allin.setChecked(True)
def slot_checkBox_highlight_longest_continuous(self):
self.plot_data_and_artifact()
info("Clicked checkBox_highlight_longest_continuous.")
self.textBrowser_update("操作:点击了高亮最长连续")
def slot_checkBox_display_afterfilter(self):
self.plot_data_and_artifact()
info("Clicked checkBox_display_afterfilter.")
self.msgBox.setText("操作:点击了去除工频噪声")
def slot_checkBox_examine_tobeLabeled(self):
info("Clicked checkBox_examine_tobeLabeled.")
self.msgBox.setText("操作:点击了仅查未标片段")
def wipe_industrialFrequencyNoise(self, data, fs):
# 设计带阻滤波器Notch Filter来滤除49-51Hz的噪声
nyq = 0.5 * fs # 奈奎斯特频率
low = 49 / nyq
high = 51 / nyq
b, a = signal.iirfilter(4, [low, high], btype='bandstop', ftype='butter') # 4阶巴特沃斯带阻滤波器
return signal.lfilter(b, a, data)
def update_status(self):
if self.radioButton_10s_mode.isChecked() == True:
hour = int(((self.current_data_idx + 10000) / 1000) // 3600)
min = int((((self.current_data_idx + 10000) / 1000) % 3600) // 60)
sec = int((((self.current_data_idx + 10000) / 1000) % 3600) % 60)
elif self.radioButton_30s_mode.isChecked() == True:
hour = int(((self.current_data_idx + 30000) / 1000) // 3600)
min = int((((self.current_data_idx + 30000) / 1000) % 3600) // 60)
sec = int((((self.current_data_idx + 30000) / 1000) % 3600) % 60)
self.lineEdit_current_part_time.setText(str(hour) + "" + str(min) + "" + str(sec) + "")
self.lineEdit_data_part_num.setText(str(self.current_part_num) + "/" + str(self.data_part_num))
# 更新表格
def update_tableWidget(self):
if self.radioButton_10s_mode.isChecked() == True:
label_a = np.where(self.label == "a")[0] + 1
label_b = np.where(self.label == "b")[0] + 1
label_c = np.where(self.label == "c")[0] + 1
label_tobeLabeled = np.where(self.label == "f")[0] + 1
self.tableWidget_label10s_a.setRowCount(label_a.__len__())
self.tableWidget_label10s_b.setRowCount(label_b.__len__())
self.tableWidget_label10s_c.setRowCount(label_c.__len__())
self.tableWidget_label10s_tobeLabeled.setRowCount(label_tobeLabeled.__len__())
for row, value in enumerate(label_a):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label10s_a.setItem(row, 0, item)
for row, value in enumerate(label_b):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label10s_b.setItem(row, 0, item)
for row, value in enumerate(label_c):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label10s_c.setItem(row, 0, item)
for row, value in enumerate(label_tobeLabeled):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label10s_tobeLabeled.setItem(row, 0, item)
self.tableWidget_label10s_a.verticalScrollBar().setValue(self.tableWidget_label10s_a.verticalScrollBar().maximum())
self.tableWidget_label10s_b.verticalScrollBar().setValue(self.tableWidget_label10s_b.verticalScrollBar().maximum())
self.tableWidget_label10s_c.verticalScrollBar().setValue(self.tableWidget_label10s_c.verticalScrollBar().maximum())
elif self.radioButton_30s_mode.isChecked() == True:
label_a1 = np.where(self.label == "a")[0] + 1
label_a2 = np.where(self.label == "b")[0] + 1
label_b1 = np.where(self.label == "c")[0] + 1
label_b2 = np.where(self.label == "d")[0] + 1
label_c = np.where(self.label == "e")[0] + 1
label_tobeLabeled = np.where(self.label == "f")[0] + 1
self.tableWidget_label30s_a1.setRowCount(label_a1.__len__())
self.tableWidget_label30s_a2.setRowCount(label_a2.__len__())
self.tableWidget_label30s_b1.setRowCount(label_b1.__len__())
self.tableWidget_label30s_b2.setRowCount(label_b2.__len__())
self.tableWidget_label30s_c.setRowCount(label_c.__len__())
self.tableWidget_label30s_tobeLabeled.setRowCount(label_tobeLabeled.__len__())
for row, value in enumerate(label_a1):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label30s_a1.setItem(row, 0, item)
for row, value in enumerate(label_a2):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label30s_a2.setItem(row, 0, item)
for row, value in enumerate(label_b1):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label30s_b1.setItem(row, 0, item)
for row, value in enumerate(label_b2):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label30s_b2.setItem(row, 0, item)
for row, value in enumerate(label_c):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label30s_c.setItem(row, 0, item)
for row, value in enumerate(label_tobeLabeled):
item = QTableWidgetItem(str(value).strip())
self.tableWidget_label30s_tobeLabeled.setItem(row, 0, item)
self.tableWidget_label30s_a1.verticalScrollBar().setValue(self.tableWidget_label30s_a1.verticalScrollBar().maximum())
self.tableWidget_label30s_a2.verticalScrollBar().setValue(self.tableWidget_label30s_a2.verticalScrollBar().maximum())
self.tableWidget_label30s_b1.verticalScrollBar().setValue(self.tableWidget_label30s_b1.verticalScrollBar().maximum())
self.tableWidget_label30s_b2.verticalScrollBar().setValue(self.tableWidget_label30s_b2.verticalScrollBar().maximum())
self.tableWidget_label30s_c.verticalScrollBar().setValue(self.tableWidget_label30s_c.verticalScrollBar().maximum())
def slot_tableWidget_label10s_a_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label10s_a.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 10000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label10s_b_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label10s_b.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 10000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label10s_c_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label10s_c.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 10000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label10s_tobeLabeled_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label10s_tobeLabeled.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 10000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label30s_a1_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label30s_a1.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 30000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label30s_a2_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label30s_a2.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 30000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label30s_b1_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label30s_b1.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 30000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label30s_b2_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label30s_b2.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 30000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label30s_c_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label30s_c.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 30000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_tableWidget_label30s_tobeLabeled_on_cell_double_clicked(self, row, column):
self.last_data_idx = self.current_data_idx
self.current_part_num = int(self.tableWidget_label30s_tobeLabeled.item(row, column).text())
self.current_data_idx = (self.current_part_num - 1) * 30000
# 更新备注内容
if not str(self.df_label.at[self.current_part_num - 1, "remark"]) == "nan":
self.lineEdit_remark.setText(str(self.df_label.at[self.current_part_num - 1, "remark"]))
else:
self.lineEdit_remark.setText("")
# 更新按钮颜色
self.change_labelBtn_color()
if (self.df_label["label"] != "f").all():
self.textBrowser_update(f"提示:该份数据打标已全部完成")
self.update_status()
self.plot_data_and_artifact()
info(f"Jumped to the {self.current_part_num} Part.")
self.textBrowser_update(f"操作:跳转到目标片段,第{self.current_part_num}")
def slot_btn_label(self):
if self.sender() == self.pushButton_label10s_a:
self.label[self.current_part_num - 1] = "a"
if self.sender() == self.pushButton_label10s_b:
self.label[self.current_part_num - 1] = "b"
if self.sender() == self.pushButton_label10s_c:
self.label[self.current_part_num - 1] = "c"
if self.sender() == self.pushButton_label10s_f:
self.label[self.current_part_num - 1] = "f"
if self.sender() == self.pushButton_label30s_a1:
self.label[self.current_part_num - 1] = "a"
if self.sender() == self.pushButton_label30s_a2:
self.label[self.current_part_num - 1] = "b"
if self.sender() == self.pushButton_label30s_b1:
self.label[self.current_part_num - 1] = "c"
if self.sender() == self.pushButton_label30s_b2:
self.label[self.current_part_num - 1] = "d"
if self.sender() == self.pushButton_label30s_c:
self.label[self.current_part_num - 1] = "e"
if self.sender() == self.pushButton_label30s_f:
self.label[self.current_part_num - 1] = "f"
self.df_label["label"] = self.label
self.df_label.at[self.current_part_num - 1, "remark"] = self.lineEdit_remark.text()
self.df_label.to_csv(self.lineEdit_savepath.text(), index=False, encoding="gbk")
self.slot_btn_right()
self.update_tableWidget()
def slot_btn_invalid_signal_label(self):
info(f"Asked whether Label All Parts to Type C.")
self.textBrowser_update(f"警告询问是否将所有片段标记为类型C")
reply = QMessageBox.question(self, "警告:确认操作", "你确定要将所有片段标记为类型C吗", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
if self.radioButton_10s_mode.isChecked() == True:
self.label = np.full(self.label.shape, "c", dtype="str")
elif self.radioButton_30s_mode.isChecked() == True:
self.label = np.full(self.label.shape, "e", dtype="str")
self.df_label["label"] = self.label
self.df_label.to_csv(self.lineEdit_savepath.text(), index=False, encoding="gbk")
self.update_tableWidget()
info(f"Labeled All Parts to Type C.")
self.textBrowser_update(f"操作已将所有片段标记为类型C")
self.msgBox.setText("已将所有片段标记为类型C")
self.msgBox.setIcon(QMessageBox.Information)
self.msgBox.exec()
else:
info(f"Operation Canceled.")
self.textBrowser_update(f"提示:操作已取消")
def slot_btn_Ctype_signal_label(self):
info(f"Asked whether Label All Parts with Artifact to Type C.")
self.textBrowser_update(f"警告询问是否将所有带有体动的片段标记为类型C")
reply = QMessageBox.question(self, "警告:确认操作", "你确定要将所有片段标记为类型C吗", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
artifact_mask = self.artifact_mask[:10000 * int(len(self.data) // 10000)]
sub_artifact_mask = np.split(artifact_mask, len(artifact_mask) // 10000)
for index, array in enumerate(sub_artifact_mask):
if 1 in array or 2 in array or 3 in array or 4 in array or 5 in array:
self.label[index] = "c"
self.df_label["label"] = self.label
self.df_label.to_csv(self.lineEdit_savepath.text(), index=False, encoding="gbk")
self.update_tableWidget()
info(f"Labeled Parts With Artifact to Type C.")
self.textBrowser_update(f"操作已将所有带有体动的片段标记为类型C")
self.msgBox.setText("已将所有带有体动的片段标记为类型C")
self.msgBox.setIcon(QMessageBox.Information)
self.msgBox.exec()
else:
info(f"Operation Canceled.")
self.textBrowser_update(f"提示:操作已取消")
def plot_data_and_artifact(self):
self.ax0.clear()
artifact_type_seq = np.array([])
artifact_type_seq = artifact_type_seq.astype(np.int64)
if self.checkBox_type1.isChecked():
artifact_type_seq = np.append(artifact_type_seq, 1)
if self.checkBox_type2.isChecked():
artifact_type_seq = np.append(artifact_type_seq, 2)
if self.checkBox_type3.isChecked():
artifact_type_seq = np.append(artifact_type_seq, 3)
if self.checkBox_type4.isChecked():
artifact_type_seq = np.append(artifact_type_seq, 4)
if self.checkBox_type5.isChecked():
artifact_type_seq = np.append(artifact_type_seq, 5)
# 是否显示去除工频噪声
if self.checkBox_display_afterfilter.isChecked():
display_data = self.data_without_industrialFrequencyNoise
else:
display_data = self.data
# 绘制数据和体动
if self.radioButton_10s_mode.isChecked() == True:
mask = np.array([np.arange(10000), np.arange(10000), np.arange(10000), np.arange(10000), np.arange(10000), np.arange(10000)])
mask = mask.astype('float')
if self.current_data_idx != self.last_data_idx:
self.data_plot, = self.ax0.plot(np.arange(self.current_data_idx, self.current_data_idx + 10000), display_data[self.current_data_idx: self.current_data_idx + 10000], label="bcg_data", color='r')
for i in artifact_type_seq:
mask[i] = self.artifact_mask[self.current_data_idx: self.current_data_idx + 10000] == i
mask[i] = (display_data[self.current_data_idx: self.current_data_idx + 10000] * mask[i]).astype('float')
np.place(mask[i], mask[i] == 0, nan)
self.artifact_plot, = self.ax0.plot(np.arange(self.current_data_idx, self.current_data_idx + 10000), mask[i], color='g', linestyle="-")
isArtifact = mask[~np.all(mask == range(0, 10000), axis=1)]
isArtifact = ~np.isnan(isArtifact).all(axis=0)
# 计算最长连续时间并更新信息
longest_continuous_max_length = 0
longest_continuous_last_length = 0
longest_continuous_current_length = 0
longest_continuous_start = 0
longest_continuous_end = 0
for index, value in enumerate(isArtifact):
if value == False:
longest_continuous_current_length += 1
if longest_continuous_current_length > longest_continuous_max_length:
longest_continuous_end = index
longest_continuous_max_length = max(longest_continuous_max_length, longest_continuous_current_length)
else:
longest_continuous_current_length = 0
longest_continuous_start = longest_continuous_end - longest_continuous_max_length + 1
if self.checkBox_highlight_longest_continuous.isChecked():
self.longest_continuous_plot, = self.ax0.plot(np.arange(self.current_data_idx + longest_continuous_start, self.current_data_idx + longest_continuous_end), display_data[self.current_data_idx + longest_continuous_start: self.current_data_idx + longest_continuous_end], color='m', linestyle="-", zorder=3)
self.lineEdit_longest_continuous_time.setText(str(round(longest_continuous_max_length / 1000, 2)) + "")
# 计算体动时间占比并更新信息
self.lineEdit_artifact_time_percentage.setText(str(round(100 * np.count_nonzero(isArtifact) / len(isArtifact), 2)) + "%")
elif self.radioButton_30s_mode.isChecked() == True:
mask = np.array([np.arange(30000), np.arange(30000), np.arange(30000), np.arange(30000), np.arange(30000), np.arange(30000)])
mask = mask.astype('float')
if self.current_data_idx != self.last_data_idx:
self.data_plot, = self.ax0.plot(np.arange(self.current_data_idx, self.current_data_idx + 30000), display_data[self.current_data_idx: self.current_data_idx + 30000], label="bcg_data", color='r')
for i in artifact_type_seq:
mask[i] = self.artifact_mask[self.current_data_idx: self.current_data_idx + 30000] == i
mask[i] = (display_data[self.current_data_idx: self.current_data_idx + 30000] * mask[i]).astype('float')
np.place(mask[i], mask[i] == 0, nan)
self.artifact_plot, = self.ax0.plot(np.arange(self.current_data_idx, self.current_data_idx + 30000), mask[i], color='g', linestyle="-")
isArtifact = mask[~np.all(mask == range(0, 30000), axis=1)]
isArtifact = ~np.isnan(isArtifact).all(axis=0)
# 计算最长连续时间并更新信息
longest_continuous_max_length = 0
longest_continuous_last_length = 0
longest_continuous_current_length = 0
longest_continuous_start = 0
longest_continuous_end = 0
for index, value in enumerate(isArtifact):
if value == False:
longest_continuous_current_length += 1
if longest_continuous_current_length > longest_continuous_max_length:
longest_continuous_end = index
longest_continuous_max_length = max(longest_continuous_max_length, longest_continuous_current_length)
else:
longest_continuous_current_length = 0
longest_continuous_start = longest_continuous_end - longest_continuous_max_length + 1
if self.checkBox_highlight_longest_continuous.isChecked():
self.longest_continuous_plot, = self.ax0.plot(np.arange(self.current_data_idx + longest_continuous_start, self.current_data_idx + longest_continuous_end), display_data[self.current_data_idx+ longest_continuous_start: self.current_data_idx + longest_continuous_end], color='m', linestyle="-", zorder=3)
self.lineEdit_longest_continuous_time.setText(str(round(longest_continuous_max_length / 1000, 2)) + "")
# 计算体动时间占比并更新信息
self.lineEdit_artifact_time_percentage.setText(str(round(100 * np.count_nonzero(isArtifact) / len(isArtifact), 2)) + "%")
self.ax0.grid(True)
self.canvas.draw()
def change_labelBtn_color(self):
if self.df_label.at[self.current_part_num - 1, "label"] == "a":
self.pushButton_label10s_a.setStyleSheet("""
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}""")
self.pushButton_label10s_b.setStyleSheet("")
self.pushButton_label10s_c.setStyleSheet("")
self.pushButton_label30s_a1.setStyleSheet("""
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}""")
self.pushButton_label30s_a2.setStyleSheet("")
self.pushButton_label30s_b1.setStyleSheet("")
self.pushButton_label30s_b2.setStyleSheet("")
self.pushButton_label30s_c.setStyleSheet("")
elif self.df_label.at[self.current_part_num - 1, "label"] == "b":
self.pushButton_label10s_a.setStyleSheet("")
self.pushButton_label10s_b.setStyleSheet("""
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}""")
self.pushButton_label10s_c.setStyleSheet("")
self.pushButton_label30s_a1.setStyleSheet("")
self.pushButton_label30s_a2.setStyleSheet("""
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}""")
self.pushButton_label30s_b1.setStyleSheet("")
self.pushButton_label30s_b2.setStyleSheet("")
self.pushButton_label30s_c.setStyleSheet("")
elif self.df_label.at[self.current_part_num - 1, "label"] == "c":
self.pushButton_label10s_a.setStyleSheet("")
self.pushButton_label10s_b.setStyleSheet("")
self.pushButton_label10s_c.setStyleSheet("""
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}""")
self.pushButton_label30s_a1.setStyleSheet("")
self.pushButton_label30s_a2.setStyleSheet("")
self.pushButton_label30s_b1.setStyleSheet("""
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}""")
self.pushButton_label30s_b2.setStyleSheet("")
self.pushButton_label30s_c.setStyleSheet("")
elif self.df_label.at[self.current_part_num - 1, "label"] == "d":
self.pushButton_label10s_a.setStyleSheet("")
self.pushButton_label10s_b.setStyleSheet("")
self.pushButton_label10s_c.setStyleSheet("")
self.pushButton_label30s_a1.setStyleSheet("")
self.pushButton_label30s_a2.setStyleSheet("")
self.pushButton_label30s_b1.setStyleSheet("")
self.pushButton_label30s_b2.setStyleSheet("""
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}""")
self.pushButton_label30s_c.setStyleSheet("")
elif self.df_label.at[self.current_part_num - 1, "label"] == "e":
self.pushButton_label10s_a.setStyleSheet("")
self.pushButton_label10s_b.setStyleSheet("")
self.pushButton_label10s_c.setStyleSheet("")
self.pushButton_label30s_a1.setStyleSheet("")
self.pushButton_label30s_a2.setStyleSheet("")
self.pushButton_label30s_b1.setStyleSheet("")
self.pushButton_label30s_b2.setStyleSheet("")
self.pushButton_label30s_c.setStyleSheet("""
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}""")
elif self.df_label.at[self.current_part_num - 1, "label"] == "f":
self.pushButton_label10s_a.setStyleSheet("")
self.pushButton_label10s_b.setStyleSheet("")
self.pushButton_label10s_c.setStyleSheet("")
self.pushButton_label30s_a1.setStyleSheet("")
self.pushButton_label30s_a2.setStyleSheet("")
self.pushButton_label30s_b1.setStyleSheet("")
self.pushButton_label30s_b2.setStyleSheet("")
self.pushButton_label30s_c.setStyleSheet("")
def textBrowser_update(self, message):
self.textBrowser_infoOutput.append(str(datetime.now().strftime("%H:%M:%S")) + ": " + message)
2025-02-21 19:12:51 +08:00
self.textBrowser_infoOutput.verticalScrollBar().setValue(self.textBrowser_infoOutput.verticalScrollBar().maximum())
2025-02-14 16:29:13 +08:00
# 主函数
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())