bcg_quality_label/bcg_quality_label.py
2025-02-21 20:41:16 +08:00

1171 lines
62 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
@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
from pandas import DataFrame, read_csv
from matplotlib.ticker import FuncFormatter
from numpy import nan
from matplotlib import use
from matplotlib import pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT
from datetime import datetime
from pathlib import Path
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QMessageBox, QButtonGroup, QApplication, QTableWidgetItem, QTableWidget
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)
self.lineEdit_savepath.setText(str(Path(self.lineEdit_savepath.text()) / "SQ_label_10s.csv"))
elif self.radioButton_30s_mode.isChecked():
self.data_part_num = len(self.data) // 30000
self.groupBox_labelDisplay_30s.setVisible(True)
self.lineEdit_savepath.setText(str(Path(self.lineEdit_savepath.text()) / "SQ_label_30s.csv"))
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)
if not Path(self.lineEdit_savepath.text()).exists():
info("Not Found History Archive csv File, Made new csv File.")
self.textBrowser_update("提示未找到历史存档csv文件创建新的csv文件")
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:
info("Found History Archive csv File, Loaded History Archive csv File.")
self.textBrowser_update("提示找到历史存档csv文件载入历史存档csv文件")
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()))
# 界面状态更新
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)
self.textBrowser_infoOutput.verticalScrollBar().setValue(self.textBrowser_infoOutput.verticalScrollBar().maximum())
# 主函数
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())