1594 lines
83 KiB
Python
1594 lines
83 KiB
Python
from gc import collect
|
||
from pathlib import Path
|
||
from traceback import format_exc
|
||
|
||
import matplotlib.pyplot as plt
|
||
from PySide6.QtCore import QCoreApplication, QTimer
|
||
from PySide6.QtGui import QAction, QFont
|
||
from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication, QTableWidget, QTableWidgetItem, QHeaderView
|
||
from matplotlib import gridspec, patches
|
||
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
||
from numpy import array, sum as np_sum, nonzero
|
||
from numpy.fft import fft, fftfreq
|
||
from overrides import overrides
|
||
from pandas import read_csv, DataFrame, concat
|
||
from scipy.signal import resample
|
||
from yaml import dump, load, FullLoader
|
||
|
||
from func.utils.ConfigParams import Filename, Params
|
||
from func.utils.PublicFunc import PublicFunc
|
||
from func.utils.Constants import Constants
|
||
from func.utils.Result import Result
|
||
|
||
from ui.MainWindow.MainWindow_artifact_label import Ui_MainWindow_artifact_label
|
||
from ui.setting.artifact_label_input_setting import Ui_MainWindow_artifact_label_input_setting
|
||
|
||
|
||
Config = {
|
||
|
||
}
|
||
|
||
ButtonState = {
|
||
"Default": {
|
||
"pushButton_input_setting": True,
|
||
"pushButton_input": True,
|
||
"pushButton_save": False,
|
||
"pushButton_prev_move": False,
|
||
"pushButton_pause": False,
|
||
"pushButton_next_move": False,
|
||
"pushButton_type_1": False,
|
||
"pushButton_type_2": False,
|
||
"pushButton_type_3": False,
|
||
"pushButton_type_4": False,
|
||
"pushButton_type_5": False,
|
||
"pushButton_delete": False
|
||
},
|
||
"Current": {
|
||
"pushButton_input_setting": True,
|
||
"pushButton_input": True,
|
||
"pushButton_save": False,
|
||
"pushButton_prev_move": False,
|
||
"pushButton_pause": False,
|
||
"pushButton_next_move": False,
|
||
"pushButton_type_1": False,
|
||
"pushButton_type_2": False,
|
||
"pushButton_type_3": False,
|
||
"pushButton_type_4": False,
|
||
"pushButton_type_5": False,
|
||
"pushButton_delete": False
|
||
}
|
||
}
|
||
|
||
|
||
class SettingWindow(QMainWindow):
|
||
|
||
def __init__(self, root_path, sampID):
|
||
super(SettingWindow, self).__init__()
|
||
self.ui = Ui_MainWindow_artifact_label_input_setting()
|
||
self.ui.setupUi(self)
|
||
|
||
self.root_path = root_path
|
||
self.sampID = sampID
|
||
|
||
self.msgBox = QMessageBox()
|
||
self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE)
|
||
|
||
self.config = None
|
||
self.__read_config__()
|
||
self.__examine_freq__()
|
||
|
||
self.ui.spinBox_input_freq_orgBcg.valueChanged.connect(self.__update_ui__)
|
||
self.ui.spinBox_input_freq_BCG.valueChanged.connect(self.__update_ui__)
|
||
self.ui.pushButton_confirm.clicked.connect(self.__write_config__)
|
||
self.ui.pushButton_cancel.clicked.connect(self.__rollback_config__)
|
||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||
|
||
def __read_config__(self):
|
||
if not Path(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH).exists():
|
||
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||
dump(Params.ARTIFACT_LABEL_CONFIG_NEW_CONTENT, f)
|
||
|
||
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "r") as f:
|
||
file_config = load(f.read(), Loader=FullLoader)
|
||
Config.update(file_config)
|
||
self.config = file_config
|
||
|
||
Config.update({
|
||
"Path": {
|
||
"Input_orgBcg": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
|
||
Path(str(self.sampID)))),
|
||
"Input_BCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
|
||
Path(str(self.sampID)))),
|
||
"Save_a": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||
Path(str(self.sampID)))),
|
||
"Save_b": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||
Path(str(self.sampID)))),
|
||
"Save_c": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||
Path(str(self.sampID))))
|
||
}
|
||
})
|
||
|
||
# 数据回显
|
||
self.ui.spinBox_input_freq_orgBcg.setValue(Config["InputConfig"]["orgBcgFreq"])
|
||
self.ui.spinBox_input_freq_BCG.setValue(Config["InputConfig"]["BCGFreq"])
|
||
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(Config["Path"]["Input_orgBcg"])
|
||
self.ui.plainTextEdit_file_path_input_BCG.setPlainText(Config["Path"]["Input_BCG"])
|
||
self.ui.plainTextEdit_file_path_save_a.setPlainText(Config["Path"]["Save_a"])
|
||
self.ui.plainTextEdit_file_path_save_b.setPlainText(Config["Path"]["Save_b"])
|
||
self.ui.plainTextEdit_file_path_save_c.setPlainText(Config["Path"]["Save_c"])
|
||
|
||
def __write_config__(self):
|
||
# 从界面写入配置
|
||
Config["InputConfig"]["orgBcgFreq"] = self.ui.spinBox_input_freq_orgBcg.value()
|
||
Config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.value()
|
||
Config["Path"]["Input_orgBcg"] = self.ui.plainTextEdit_file_path_input_orgBcg.toPlainText()
|
||
Config["Path"]["Input_BCG"] = self.ui.plainTextEdit_file_path_input_BCG.toPlainText()
|
||
Config["Path"]["Save_a"] = self.ui.plainTextEdit_file_path_save_a.toPlainText()
|
||
Config["Path"]["Save_b"] = self.ui.plainTextEdit_file_path_save_b.toPlainText()
|
||
Config["Path"]["Save_c"] = self.ui.plainTextEdit_file_path_save_c.toPlainText()
|
||
|
||
# 保存配置到文件
|
||
self.config["InputConfig"]["orgBcgFreq"] = self.ui.spinBox_input_freq_orgBcg.value()
|
||
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.value()
|
||
|
||
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||
dump(self.config, f)
|
||
|
||
self.close()
|
||
|
||
def __rollback_config__(self):
|
||
self.__read_config__()
|
||
|
||
def __update_ui__(self):
|
||
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
|
||
str((Path(self.root_path) /
|
||
Filename.PATH_ORGBCG_ALIGNED /
|
||
Path(str(self.sampID)) /
|
||
Path(Filename.ORGBCG_SYNC +
|
||
str(self.ui.spinBox_input_freq_orgBcg.value()) +
|
||
Params.ENDSWITH_TXT))))
|
||
self.ui.plainTextEdit_file_path_input_BCG.setPlainText(
|
||
str((Path(self.root_path) /
|
||
Filename.PATH_ORGBCG_ALIGNED /
|
||
Path(str(self.sampID)) /
|
||
Path(Filename.BCG_SYNC +
|
||
str(self.ui.spinBox_input_freq_BCG.value()) +
|
||
Params.ENDSWITH_TXT))))
|
||
|
||
def __examine_freq__(self):
|
||
if Path(Config["Path"]["Input_orgBcg"]).is_file():
|
||
Config["Path"]["Input_orgBcg"] = str(Path(Config["Path"]["Input_orgBcg"]).parent)
|
||
if Path(Config["Path"]["Input_BCG"]).is_file():
|
||
Config["Path"]["Input_BCG"] = str(Path(Config["Path"]["Input_BCG"]).parent)
|
||
|
||
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
|
||
if result.status:
|
||
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
|
||
else:
|
||
PublicFunc.msgbox_output(self, Filename.ORGBCG_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR)
|
||
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_SYNC, Params.ENDSWITH_TXT)
|
||
if result.status:
|
||
Config["InputConfig"]["BCGFreq"] = result.data["freq"]
|
||
else:
|
||
PublicFunc.msgbox_output(self, Filename.BCG_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR)
|
||
|
||
# 数据回显
|
||
self.ui.spinBox_input_freq_orgBcg.setValue(Config["InputConfig"]["orgBcgFreq"])
|
||
self.ui.spinBox_input_freq_BCG.setValue(Config["InputConfig"]["BCGFreq"])
|
||
|
||
|
||
class MainWindow_artifact_label(QMainWindow):
|
||
|
||
def __init__(self):
|
||
super(MainWindow_artifact_label, self).__init__()
|
||
self.ui = Ui_MainWindow_artifact_label()
|
||
self.ui.setupUi(self)
|
||
|
||
self.root_path = None
|
||
self.sampID = None
|
||
|
||
self.data = None
|
||
|
||
self.setting = None
|
||
|
||
# 初始化进度条
|
||
self.progressbar = None
|
||
PublicFunc.add_progressbar(self)
|
||
|
||
#初始化画框
|
||
self.fig = None
|
||
self.canvas = None
|
||
self.figToolbar = None
|
||
self.gs = None
|
||
self.ax0 = None
|
||
self.ax1 = None
|
||
self.rectangles_ax0_patches = []
|
||
self.rectangles_ax1_patches = []
|
||
self.annotation_tableWidget = None
|
||
self.rect_left = None
|
||
self.rect_right = None
|
||
self.is_left_button_pressed = None
|
||
self.pressed_number = None
|
||
|
||
self.rect_up = None
|
||
self.rect_down = None
|
||
|
||
# 初始化自动播放定时器
|
||
self.autoplay_xlim_start = None
|
||
self.autoplay_xlim_end = None
|
||
self.timer_autoplay = QTimer()
|
||
self.timer_autoplay.timeout.connect(self.autoplay_move_xlim)
|
||
Config.update({
|
||
"AutoplayArgs": {
|
||
"AutoplayMode": "pause",
|
||
"MoveLength": int(self.ui.label_moveLength_preset_1.text()),
|
||
"MaxRange": int(self.ui.label_maxRange_preset_1.text()),
|
||
"MoveSpeed": int(self.ui.label_moveSpeed_preset_1.text())
|
||
}
|
||
})
|
||
|
||
self.msgBox = QMessageBox()
|
||
self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE)
|
||
|
||
@overrides
|
||
def show(self, root_path, sampID):
|
||
super().show()
|
||
self.root_path = root_path
|
||
self.sampID = sampID
|
||
|
||
self.setting = SettingWindow(root_path, sampID)
|
||
|
||
# 初始化画框
|
||
self.fig = plt.figure(figsize=(12, 9), dpi=100)
|
||
self.canvas = FigureCanvasQTAgg(self.fig)
|
||
self.figToolbar = CustomNavigationToolbar(self.canvas, self)
|
||
self.figToolbar.action_Label_Artifact.setEnabled(False)
|
||
for action in self.figToolbar._actions.values():
|
||
action.setEnabled(False)
|
||
for action in self.figToolbar.actions():
|
||
if action.text() == "Subplots" or action.text() == "Customize":
|
||
self.figToolbar.removeAction(action)
|
||
self.figToolbar._actions['home'].triggered.connect(self.toggle_home)
|
||
self.figToolbar._actions['zoom'].triggered.connect(self.toggle_zoom)
|
||
self.figToolbar._actions['pan'].triggered.connect(self.toggle_pan)
|
||
self.figToolbar.action_Label_Artifact.triggered.connect(self.toggle_label_artifact)
|
||
self.ui.verticalLayout_canvas.addWidget(self.canvas)
|
||
self.ui.verticalLayout_canvas.addWidget(self.figToolbar)
|
||
self.gs = gridspec.GridSpec(2, 1, height_ratios=[1, 1])
|
||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||
self.ax0.grid(True)
|
||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
|
||
self.ax1.grid(True)
|
||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||
|
||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||
|
||
self.ui.spinBox_moveLength.setValue(Config["CustomAutoplayArgs"]["MoveLength"])
|
||
self.ui.spinBox_maxRange.setValue(Config["CustomAutoplayArgs"]["MaxRange"])
|
||
self.ui.spinBox_moveSpeed.setValue(Config["CustomAutoplayArgs"]["MoveSpeed"])
|
||
|
||
self.ui.tableWidget_type_1.setHorizontalHeaderLabels(['序号', '起始时间', '终止时间'])
|
||
self.ui.tableWidget_type_2.setHorizontalHeaderLabels(['序号', '起始时间', '终止时间'])
|
||
self.ui.tableWidget_type_3.setHorizontalHeaderLabels(['序号', '起始时间', '终止时间'])
|
||
self.ui.tableWidget_type_4.setHorizontalHeaderLabels(['序号', '起始时间', '终止时间'])
|
||
self.ui.tableWidget_type_5.setHorizontalHeaderLabels(['序号', '起始时间', '终止时间'])
|
||
self.ui.tableWidget_type_1.setEditTriggers(QTableWidget.NoEditTriggers)
|
||
self.ui.tableWidget_type_2.setEditTriggers(QTableWidget.NoEditTriggers)
|
||
self.ui.tableWidget_type_3.setEditTriggers(QTableWidget.NoEditTriggers)
|
||
self.ui.tableWidget_type_4.setEditTriggers(QTableWidget.NoEditTriggers)
|
||
self.ui.tableWidget_type_5.setEditTriggers(QTableWidget.NoEditTriggers)
|
||
self.ui.tableWidget_type_1.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||
self.ui.tableWidget_type_2.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||
self.ui.tableWidget_type_3.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||
self.ui.tableWidget_type_4.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||
self.ui.tableWidget_type_5.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||
|
||
self.ui.lineEdit_start_time.setValidator(Params.VALIDATOR_INTEGER)
|
||
self.ui.lineEdit_end_time.setValidator(Params.VALIDATOR_INTEGER)
|
||
|
||
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
|
||
self.ui.pushButton_type_1.clicked.connect(self.__slot_btn_label__)
|
||
self.ui.pushButton_type_2.clicked.connect(self.__slot_btn_label__)
|
||
self.ui.pushButton_type_3.clicked.connect(self.__slot_btn_label__)
|
||
self.ui.pushButton_type_4.clicked.connect(self.__slot_btn_label__)
|
||
self.ui.pushButton_type_5.clicked.connect(self.__slot_btn_label__)
|
||
self.ui.pushButton_delete.clicked.connect(self.__slot_btn_delete_label__)
|
||
self.ui.pushButton_save.clicked.connect(self.__slot_btn_save__)
|
||
self.ui.pushButton_prev_move.clicked.connect(self.__slot_btn_move__)
|
||
self.ui.pushButton_pause.clicked.connect(self.__slot_btn_move__)
|
||
self.ui.pushButton_next_move.clicked.connect(self.__slot_btn_move__)
|
||
self.ui.radioButton_move_preset_1.toggled.connect(self.__change_autoplay_args__)
|
||
self.ui.radioButton_move_preset_2.toggled.connect(self.__change_autoplay_args__)
|
||
self.ui.radioButton_move_preset_3.toggled.connect(self.__change_autoplay_args__)
|
||
self.ui.radioButton_move_custom.toggled.connect(self.__change_autoplay_args__)
|
||
self.ui.tableWidget_type_1.cellDoubleClicked.connect(self.__slot_tableWidget_on_cell_double_clicked__)
|
||
self.ui.tableWidget_type_2.cellDoubleClicked.connect(self.__slot_tableWidget_on_cell_double_clicked__)
|
||
self.ui.tableWidget_type_3.cellDoubleClicked.connect(self.__slot_tableWidget_on_cell_double_clicked__)
|
||
self.ui.tableWidget_type_4.cellDoubleClicked.connect(self.__slot_tableWidget_on_cell_double_clicked__)
|
||
self.ui.tableWidget_type_5.cellDoubleClicked.connect(self.__slot_tableWidget_on_cell_double_clicked__)
|
||
self.ui.pushButton_input_setting.clicked.connect(self.setting.show)
|
||
|
||
@overrides
|
||
def closeEvent(self, event):
|
||
reply = QMessageBox.question(self, '确认', '确认退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
||
if reply == QMessageBox.Yes:
|
||
|
||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||
|
||
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
|
||
QApplication.processEvents()
|
||
|
||
# 清空画框
|
||
del self.rectangles_ax0_patches
|
||
del self.rectangles_ax1_patches
|
||
del self.annotation_tableWidget
|
||
if self.ax0 is not None:
|
||
self.ax0.clear()
|
||
if self.ax1 is not None:
|
||
self.ax1.clear()
|
||
|
||
# 释放资源
|
||
del self.data
|
||
self.fig.clf()
|
||
plt.close(self.fig)
|
||
self.deleteLater()
|
||
collect()
|
||
self.canvas = None
|
||
event.accept()
|
||
else:
|
||
event.ignore()
|
||
|
||
def __reset__(self):
|
||
ButtonState["Current"].update(ButtonState["Default"].copy())
|
||
|
||
def __plot__(self):
|
||
# 清空画框
|
||
if self.annotation_tableWidget is not None:
|
||
self.annotation_tableWidget.remove()
|
||
self.annotation_tableWidget = None
|
||
|
||
self.reset_axes()
|
||
|
||
sender = self.sender()
|
||
|
||
if sender == self.ui.pushButton_input:
|
||
try:
|
||
self.ax0.plot(self.data.orgBcg, label=Constants.ARTIFACT_LABEL_PLOT_LABEL_ORGBCG_SYNC,
|
||
color=Constants.PLOT_COLOR_BLUE)
|
||
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
|
||
self.ax1.plot(self.data.BCG, label=Constants.ARTIFACT_LABEL_PLOT_LABEL_BCG_SYNC,
|
||
color=Constants.PLOT_COLOR_BLUE)
|
||
self.ax1.legend(loc=Constants.PLOT_UPPER_RIGHT)
|
||
self.rect_down = min(self.ax0.get_ylim()[0], self.ax1.get_ylim()[0]) - 1000
|
||
self.rect_up = max(self.ax0.get_ylim()[1], self.ax1.get_ylim()[1]) + 1000
|
||
self.canvas.draw()
|
||
self.__plot_artifact__()
|
||
self.ax0.autoscale(False)
|
||
self.ax1.autoscale(False)
|
||
except Exception as e:
|
||
return Result().failure(info=Constants.DRAW_FAILURE + "\n" + format_exc())
|
||
return Result().success(info=Constants.DRAW_FINISHED)
|
||
else:
|
||
self.canvas.draw()
|
||
self.ax0.autoscale(False)
|
||
self.ax1.autoscale(False)
|
||
return Result().failure(info=Constants.DRAW_FAILURE)
|
||
|
||
def __plot_artifact__(self):
|
||
if len(self.ax0.patches) != 0:
|
||
for patch in self.ax0.patches:
|
||
if patch in self.rectangles_ax0_patches:
|
||
patch.remove()
|
||
if len(self.ax1.patches) != 0:
|
||
for patch in self.ax1.patches:
|
||
if patch in self.rectangles_ax1_patches:
|
||
patch.remove()
|
||
|
||
self.rectangles_ax0_patches = []
|
||
self.rectangles_ax1_patches = []
|
||
self.ax1.callbacks.connect('xlim_changed', lambda ax: self.on_xlim_change(ax))
|
||
self.canvas.draw()
|
||
|
||
# 绘制体动
|
||
for i in range(0, len(self.data.df_Artifact_a)):
|
||
if self.data.df_Artifact_a.iloc[i][1] == 1:
|
||
# 橙色,剧烈体动
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_DEEP_YELLOW)
|
||
self.rectangles_ax0_patches.append(rectangle)
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_DEEP_YELLOW)
|
||
self.rectangles_ax1_patches.append(rectangle)
|
||
elif self.data.df_Artifact_a.iloc[i][1] == 2:
|
||
# 黄色,脉冲体动
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_YELLOW)
|
||
self.rectangles_ax0_patches.append(rectangle)
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_YELLOW)
|
||
self.rectangles_ax1_patches.append(rectangle)
|
||
elif self.data.df_Artifact_a.iloc[i][1] == 3:
|
||
# 青色,常规体动
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_AQUA)
|
||
self.rectangles_ax0_patches.append(rectangle)
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_AQUA)
|
||
self.rectangles_ax1_patches.append(rectangle)
|
||
elif self.data.df_Artifact_a.iloc[i][1] == 4:
|
||
# 紫色,疑似鼾声
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_PURPLE_PINK)
|
||
self.rectangles_ax0_patches.append(rectangle)
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_PURPLE_PINK)
|
||
self.rectangles_ax1_patches.append(rectangle)
|
||
elif self.data.df_Artifact_a.iloc[i][1] == 5:
|
||
# 灰色,离床
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_DEEP_GREY)
|
||
self.rectangles_ax0_patches.append(rectangle)
|
||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||
height=self.rect_up - self.rect_down,
|
||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||
color=Constants.PLOT_COLOR_DEEP_GREY)
|
||
self.rectangles_ax1_patches.append(rectangle)
|
||
for patch in self.rectangles_ax0_patches:
|
||
self.ax0.add_patch(patch)
|
||
for patch in self.rectangles_ax1_patches:
|
||
self.ax1.add_patch(patch)
|
||
|
||
self.canvas.draw()
|
||
|
||
def update_label_args(self, rect_left, rect_right):
|
||
try:
|
||
# 计算傅里叶变换
|
||
fft_result = fft(self.data.orgBcg[rect_left:rect_right])
|
||
fft_freqs = fftfreq(len(self.data.orgBcg[rect_left:rect_right]), 1 / Config["InputConfig"]["orgBcgFreq"])
|
||
# 确定频率高于20Hz的成分
|
||
high_freq_indices = abs(fft_freqs) > 20
|
||
high_freq_fft = fft_result[high_freq_indices]
|
||
# 计算能量
|
||
total_energy = sum(abs(fft_result) ** 2)
|
||
high_freq_energy = sum(abs(high_freq_fft) ** 2)
|
||
# 计算能量占比
|
||
energy_ratio_orgData_sync = round((high_freq_energy * 100 / total_energy), 6)
|
||
|
||
# 计算傅里叶变换
|
||
fft_result = fft(self.data.orgBcg[rect_left:rect_right])
|
||
fft_freqs = fftfreq(len(self.data.orgBcg[rect_left:rect_right]),
|
||
1 / Config["InputConfig"]["orgBcgFreq"])
|
||
# 确定频率高于20Hz的成分
|
||
high_freq_indices = abs(fft_freqs) > 20
|
||
high_freq_fft = fft_result[high_freq_indices]
|
||
# 计算能量
|
||
total_energy = sum(abs(fft_result) ** 2)
|
||
high_freq_energy = sum(abs(high_freq_fft) ** 2)
|
||
# 计算能量占比
|
||
energy_ratio_BCG_sync = round((high_freq_energy * 100 / total_energy), 6)
|
||
|
||
self.ui.lineEdit_energy_percent_orgBcg.setText(str(energy_ratio_orgData_sync) + "%")
|
||
self.ui.lineEdit_energy_percent_BCG.setText(str(energy_ratio_BCG_sync) + "%")
|
||
self.ui.lineEdit_start_time.setText(str(int(self.rect_left)))
|
||
self.ui.lineEdit_end_time.setText(str(int(self.rect_right)))
|
||
self.ui.lineEdit_duration.setText(str(int(self.rect_right) - int(self.rect_left)))
|
||
except Exception:
|
||
self.ui.lineEdit_energy_percent_orgBcg.setText("获取异常")
|
||
self.ui.lineEdit_energy_percent_BCG.setText("获取异常")
|
||
self.ui.lineEdit_start_time.setText("获取异常")
|
||
self.ui.lineEdit_end_time.setText("获取异常")
|
||
self.ui.lineEdit_duration.setText("获取异常")
|
||
|
||
def update_tableWidget(self):
|
||
try:
|
||
self.ui.tableWidget_type_1.clearContents()
|
||
self.ui.tableWidget_type_2.clearContents()
|
||
self.ui.tableWidget_type_3.clearContents()
|
||
self.ui.tableWidget_type_4.clearContents()
|
||
self.ui.tableWidget_type_5.clearContents()
|
||
self.ui.tableWidget_type_1.setRowCount(0)
|
||
self.ui.tableWidget_type_2.setRowCount(0)
|
||
self.ui.tableWidget_type_3.setRowCount(0)
|
||
self.ui.tableWidget_type_4.setRowCount(0)
|
||
self.ui.tableWidget_type_5.setRowCount(0)
|
||
for row, data in self.data.df_Artifact_a.iterrows():
|
||
if data["type"] == 1:
|
||
self.ui.tableWidget_type_1.setRowCount(self.ui.tableWidget_type_1.rowCount() + 1)
|
||
self.ui.tableWidget_type_1.setItem(self.ui.tableWidget_type_1.rowCount() - 1, 0, QTableWidgetItem(str(data["number"])))
|
||
self.ui.tableWidget_type_1.setItem(self.ui.tableWidget_type_1.rowCount() - 1, 1, QTableWidgetItem(str(data["startTime"])))
|
||
self.ui.tableWidget_type_1.setItem(self.ui.tableWidget_type_1.rowCount() - 1, 2, QTableWidgetItem(str(data["endTime"])))
|
||
elif data["type"] == 2:
|
||
self.ui.tableWidget_type_2.setRowCount(self.ui.tableWidget_type_2.rowCount() + 1)
|
||
self.ui.tableWidget_type_2.setItem(self.ui.tableWidget_type_2.rowCount() - 1, 0, QTableWidgetItem(str(data["number"])))
|
||
self.ui.tableWidget_type_2.setItem(self.ui.tableWidget_type_2.rowCount() - 1, 1, QTableWidgetItem(str(data["startTime"])))
|
||
self.ui.tableWidget_type_2.setItem(self.ui.tableWidget_type_2.rowCount() - 1, 2, QTableWidgetItem(str(data["endTime"])))
|
||
elif data["type"] == 3:
|
||
self.ui.tableWidget_type_3.setRowCount(self.ui.tableWidget_type_3.rowCount() + 1)
|
||
self.ui.tableWidget_type_3.setItem(self.ui.tableWidget_type_3.rowCount() - 1, 0, QTableWidgetItem(str(data["number"])))
|
||
self.ui.tableWidget_type_3.setItem(self.ui.tableWidget_type_3.rowCount() - 1, 1, QTableWidgetItem(str(data["startTime"])))
|
||
self.ui.tableWidget_type_3.setItem(self.ui.tableWidget_type_3.rowCount() - 1, 2, QTableWidgetItem(str(data["endTime"])))
|
||
elif data["type"] == 4:
|
||
self.ui.tableWidget_type_4.setRowCount(self.ui.tableWidget_type_4.rowCount() + 1)
|
||
self.ui.tableWidget_type_4.setItem(self.ui.tableWidget_type_4.rowCount() - 1, 0, QTableWidgetItem(str(data["number"])))
|
||
self.ui.tableWidget_type_4.setItem(self.ui.tableWidget_type_4.rowCount() - 1, 1, QTableWidgetItem(str(data["startTime"])))
|
||
self.ui.tableWidget_type_4.setItem(self.ui.tableWidget_type_4.rowCount() - 1, 2, QTableWidgetItem(str(data["endTime"])))
|
||
elif data["type"] == 5:
|
||
self.ui.tableWidget_type_5.setRowCount(self.ui.tableWidget_type_5.rowCount() + 1)
|
||
self.ui.tableWidget_type_5.setItem(self.ui.tableWidget_type_5.rowCount() - 1, 0, QTableWidgetItem(str(data["number"])))
|
||
self.ui.tableWidget_type_5.setItem(self.ui.tableWidget_type_5.rowCount() - 1, 1, QTableWidgetItem(str(data["startTime"])))
|
||
self.ui.tableWidget_type_5.setItem(self.ui.tableWidget_type_5.rowCount() - 1, 2, QTableWidgetItem(str(data["endTime"])))
|
||
except Exception as e:
|
||
return Result().failure(info=Constants.UPDATE_FAILURE + Constants.FAILURE_REASON["Update_tableWidget_Exception"] + "\n" + format_exc())
|
||
|
||
return Result().success(info=Constants.UPDATE_FINISHED)
|
||
|
||
def update_Info(self):
|
||
try:
|
||
artifact_amount = [0, 0, 0, 0, 0]
|
||
artifact_total_duration = [0, 0, 0, 0, 0]
|
||
tableWidget_list = [self.ui.tableWidget_type_1,
|
||
self.ui.tableWidget_type_2,
|
||
self.ui.tableWidget_type_3,
|
||
self.ui.tableWidget_type_4,
|
||
self.ui.tableWidget_type_5]
|
||
for index, tableWidget in enumerate(tableWidget_list):
|
||
sum_of_differences = 0
|
||
for row in range(tableWidget.rowCount()):
|
||
startTime = tableWidget.item(row, 1)
|
||
endTime = tableWidget.item(row, 2)
|
||
if startTime and endTime: # 确保单元格不为空
|
||
startTime = int(startTime.text())
|
||
endTime = int(endTime.text())
|
||
difference_amount = endTime - startTime
|
||
sum_of_differences += difference_amount
|
||
artifact_amount[index] = tableWidget.rowCount()
|
||
artifact_total_duration[index] = sum_of_differences
|
||
self.ui.spinBox_amount_type_1.setValue(artifact_amount[0])
|
||
self.ui.spinBox_amount_type_2.setValue(artifact_amount[1])
|
||
self.ui.spinBox_amount_type_3.setValue(artifact_amount[2])
|
||
self.ui.spinBox_amount_type_4.setValue(artifact_amount[3])
|
||
self.ui.spinBox_amount_type_5.setValue(artifact_amount[4])
|
||
self.ui.spinBox_duration_type_1.setValue(artifact_total_duration[0])
|
||
self.ui.spinBox_duration_type_2.setValue(artifact_total_duration[1])
|
||
self.ui.spinBox_duration_type_3.setValue(artifact_total_duration[2])
|
||
self.ui.spinBox_duration_type_4.setValue(artifact_total_duration[3])
|
||
self.ui.spinBox_duration_type_5.setValue(artifact_total_duration[4])
|
||
except Exception as e:
|
||
return Result().failure(info=Constants.UPDATE_FAILURE + Constants.FAILURE_REASON["Update_Info_Exception"] + "\n" + format_exc())
|
||
|
||
return Result().success(info=Constants.UPDATE_FINISHED)
|
||
|
||
def __slot_btn_input__(self):
|
||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||
|
||
self.reset_axes()
|
||
self.canvas.draw()
|
||
|
||
self.data = Data()
|
||
|
||
# 导入数据
|
||
PublicFunc.progressbar_update(self, 1, 6, Constants.INPUTTING_DATA, 0)
|
||
result = self.data.open_file()
|
||
if not result.status:
|
||
PublicFunc.text_output(self.ui, "(1/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
return
|
||
else:
|
||
PublicFunc.text_output(self.ui, "(1/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||
|
||
# 重采样
|
||
PublicFunc.progressbar_update(self, 2, 6, Constants.RESAMPLING_DATA, 0)
|
||
result = self.data.resample()
|
||
if not result.status:
|
||
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
return
|
||
else:
|
||
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||
|
||
# 获取存档
|
||
PublicFunc.progressbar_update(self, 3, 6, Constants.LOADING_ARCHIVE, 50)
|
||
result = self.data.get_archive()
|
||
if not result.status:
|
||
PublicFunc.text_output(self.ui, "(3/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
return
|
||
else:
|
||
PublicFunc.text_output(self.ui, "(3/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||
|
||
# 绘图
|
||
PublicFunc.progressbar_update(self, 4, 6, Constants.DRAWING_DATA, 60)
|
||
result = self.__plot__()
|
||
if not result.status:
|
||
PublicFunc.text_output(self.ui, "(4/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
return
|
||
else:
|
||
PublicFunc.text_output(self.ui, "(4/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||
|
||
# 更新表格
|
||
PublicFunc.progressbar_update(self, 5, 6, Constants.UPDATING_TABLEWIDGET, 90)
|
||
result = self.update_tableWidget()
|
||
if not result.status:
|
||
PublicFunc.text_output(self.ui, "(5/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
return
|
||
else:
|
||
PublicFunc.text_output(self.ui, "(5/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||
|
||
# 更新信息
|
||
PublicFunc.progressbar_update(self, 6, 6, Constants.UPDATING_INFO, 95)
|
||
result = self.update_Info()
|
||
if not result.status:
|
||
PublicFunc.text_output(self.ui, "(6/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
return
|
||
else:
|
||
PublicFunc.text_output(self.ui, "(6/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||
|
||
self.__reset__()
|
||
self.figToolbar.action_Label_Artifact.setEnabled(True)
|
||
for action in self.figToolbar._actions.values():
|
||
action.setEnabled(True)
|
||
ButtonState["Current"]["pushButton_input"] = False
|
||
ButtonState["Current"]["pushButton_input_setting"] = False
|
||
ButtonState["Current"]["pushButton_prev_move"] = True
|
||
ButtonState["Current"]["pushButton_next_move"] = True
|
||
ButtonState["Current"]["pushButton_save"] = True
|
||
ButtonState["Current"]["pushButton_pause"] = True
|
||
ButtonState["Current"]["pushButton_type_1"] = True
|
||
ButtonState["Current"]["pushButton_type_2"] = True
|
||
ButtonState["Current"]["pushButton_type_3"] = True
|
||
ButtonState["Current"]["pushButton_type_4"] = True
|
||
ButtonState["Current"]["pushButton_type_5"] = True
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
|
||
def __slot_btn_save__(self):
|
||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||
|
||
# 保存
|
||
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
|
||
result = self.save()
|
||
if not result.status:
|
||
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
return
|
||
else:
|
||
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_INFO)
|
||
|
||
PublicFunc.msgbox_output(self, result.info, Constants.TIPS_TYPE_INFO)
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
|
||
def __slot_btn_label__(self):
|
||
sender = self.sender()
|
||
select_row = []
|
||
select_type = array([0, 0, 0, 0, 0])
|
||
flagf = False
|
||
flagb = False
|
||
start_time = 0
|
||
end_time = 0
|
||
|
||
if sender == self.ui.pushButton_type_1:
|
||
type = 1
|
||
elif sender == self.ui.pushButton_type_2:
|
||
type = 2
|
||
elif sender == self.ui.pushButton_type_3:
|
||
type = 3
|
||
elif sender == self.ui.pushButton_type_4:
|
||
type = 4
|
||
elif sender == self.ui.pushButton_type_5:
|
||
type = 5
|
||
else:
|
||
raise ValueError()
|
||
|
||
if (self.ui.lineEdit_start_time.text() == Constants.STRING_IS_EMPTY or
|
||
self.ui.lineEdit_end_time.text() == Constants.STRING_IS_EMPTY):
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_MISS_ARGS, Constants.MSGBOX_TYPE_ERROR)
|
||
return
|
||
|
||
for index, row in self.data.df_Artifact_a.iterrows():
|
||
value_startTime = row['startTime']
|
||
value_endTime = row['endTime']
|
||
value_type = row['type']
|
||
|
||
if ((value_startTime <= int(self.ui.lineEdit_end_time.text()) <= value_endTime) or
|
||
(value_startTime <= int(self.ui.lineEdit_start_time.text()) <= value_endTime) or
|
||
(value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(self.ui.lineEdit_end_time.text())) or
|
||
(0 < (int(self.ui.lineEdit_start_time.text()) - value_endTime) <= (2 * Config["InputConfig"]["UseFreq"])) or
|
||
(0 < (value_startTime - int(self.ui.lineEdit_end_time.text())) <= (2 * Config["InputConfig"]["UseFreq"]))):
|
||
select_row.append(row.to_dict())
|
||
if value_type == 1:
|
||
select_type[0] = select_type[0] + 1
|
||
elif value_type == 2:
|
||
select_type[1] = select_type[1] + 1
|
||
elif value_type == 3:
|
||
select_type[2] = select_type[2] + 1
|
||
elif value_type == 4:
|
||
select_type[3] = select_type[3] + 1
|
||
elif value_type == 5:
|
||
select_type[4] = select_type[4] + 1
|
||
if (0 < (int(self.ui.lineEdit_start_time.text()) - value_endTime) <= (2 * Config["InputConfig"]["UseFreq"])):
|
||
flagf = True
|
||
if (0 < (value_startTime - int(self.ui.lineEdit_end_time.text())) <= (2 * Config["InputConfig"]["UseFreq"])):
|
||
flagb = True
|
||
|
||
# 按照括注的体动的数量来进行条件判断
|
||
if len(select_row) >= 1:
|
||
if flagf == True and flagb == False:
|
||
start_time = select_row[0]['startTime']
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
typef = select_row[0]['type']
|
||
if typef == 1 or typef == 2 or typef == 3:
|
||
if type == 1:
|
||
type = 1
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
elif type == 2:
|
||
if typef == 1:
|
||
type = 1
|
||
elif typef == 2:
|
||
type = 3
|
||
elif typef == 3:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
elif type == 3:
|
||
if typef == 1:
|
||
type = 1
|
||
elif typef == 2:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
elif typef == 3:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
else:
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_WARNING,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
select_row = select_row[1:]
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
elif typef == 4 or typef == 5:
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_WARNING,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
select_row = select_row[1:]
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
elif flagf == False and flagb == True:
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = select_row[-1]['endTime']
|
||
typeb = select_row[-1]['type']
|
||
if typeb == 1 or typeb == 2 or typeb == 3:
|
||
if type == 1:
|
||
type = 1
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
elif type == 2:
|
||
if typeb == 1:
|
||
type = 1
|
||
elif typeb == 2:
|
||
type = 3
|
||
elif typeb == 3:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
elif type == 3:
|
||
if typeb == 1:
|
||
type = 1
|
||
elif typeb == 2:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
elif typeb == 3:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
else:
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_WARNING,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
select_row = select_row[:-1]
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
elif typeb == 4 or typeb == 5:
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_WARNING,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
select_row = select_row[:-1]
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
elif flagf == True and flagb == True:
|
||
start_time = select_row[0]['startTime']
|
||
end_time = select_row[-1]['endTime']
|
||
typef = select_row[0]['type']
|
||
typeb = select_row[-1]['type']
|
||
if typef == 1 or typef == 2 or typef == 3:
|
||
if type == 1:
|
||
type = 1
|
||
elif type == 2:
|
||
if typef == 1:
|
||
type = 1
|
||
elif typef == 2:
|
||
type = 3
|
||
elif typef == 3:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
elif type == 3:
|
||
if typef == 1:
|
||
type = 1
|
||
elif typef == 2:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
elif typef == 3:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
if type == 1:
|
||
type = 1
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
elif type == 2:
|
||
if typeb == 1:
|
||
type = 1
|
||
elif typeb == 2:
|
||
type = 3
|
||
elif typeb == 3:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
elif type == 3:
|
||
if typeb == 1:
|
||
type = 1
|
||
elif typeb == 2:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
elif typeb == 3:
|
||
if end_time - start_time >= (5 * Config["InputConfig"]["UseFreq"]):
|
||
type = 1
|
||
else:
|
||
type = 3
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
else:
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_WARNING,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
select_row = select_row[1:-1]
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
elif typef == 4 or typef == 5:
|
||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_WARNING,
|
||
Constants.MSGBOX_TYPE_INFO)
|
||
select_row = select_row[1:-1]
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
elif flagf == False and flagb == False:
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
else:
|
||
start_time = int(self.ui.lineEdit_start_time.text())
|
||
end_time = int(self.ui.lineEdit_end_time.text())
|
||
|
||
for select_each_row in select_row:
|
||
self.data.df_Artifact_a = self.data.df_Artifact_a[self.data.df_Artifact_a['number'] != select_each_row["number"]]
|
||
|
||
new_row = {
|
||
'number': 1,
|
||
'type': int(type),
|
||
'startTime': start_time,
|
||
'endTime': end_time
|
||
}
|
||
|
||
self.data.df_Artifact_a = concat([self.data.df_Artifact_a, DataFrame([new_row])], ignore_index=True)
|
||
self.data.df_Artifact_a[['type', 'startTime', 'endTime']] = self.data.df_Artifact_a[['type', 'startTime', 'endTime']].sort_values(by='startTime').reset_index(
|
||
drop=True)
|
||
self.data.df_Artifact_a['number'] = range(1, len(self.data.df_Artifact_a) + 1)
|
||
|
||
self.update_tableWidget()
|
||
self.update_Info()
|
||
self.__plot_artifact__()
|
||
|
||
target_row = self.data.df_Artifact_a[self.data.df_Artifact_a.eq(start_time).any(axis=1)]
|
||
if not target_row.empty:
|
||
first_column_value = target_row.iloc[0, 0] # 获取第1列的值
|
||
else:
|
||
raise AttributeError()
|
||
|
||
PublicFunc.text_output(self.ui, f"新增体动标签{first_column_value}, 类型{new_row['type']},从{int(start_time)}ms到{int(end_time)}ms", Constants.TIPS_TYPE_INFO)
|
||
|
||
self.save()
|
||
|
||
def save(self):
|
||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||
|
||
# 保存
|
||
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
|
||
|
||
amount = [
|
||
self.ui.spinBox_amount_type_1.value(),
|
||
self.ui.spinBox_amount_type_2.value(),
|
||
self.ui.spinBox_amount_type_3.value(),
|
||
self.ui.spinBox_amount_type_4.value(),
|
||
self.ui.spinBox_amount_type_5.value()
|
||
]
|
||
duration = [
|
||
self.ui.spinBox_duration_type_1.value(),
|
||
self.ui.spinBox_duration_type_2.value(),
|
||
self.ui.spinBox_duration_type_3.value(),
|
||
self.ui.spinBox_duration_type_4.value(),
|
||
self.ui.spinBox_duration_type_5.value()
|
||
]
|
||
|
||
result = self.data.save(amount, duration)
|
||
|
||
if not result.status:
|
||
info = f"未成功保存,错误提示:{result.info},结果已暂存到缓存中,请正确操作后重试。"
|
||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||
else:
|
||
info = result.info
|
||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||
|
||
PublicFunc.finish_operation(self, ButtonState)
|
||
return result
|
||
|
||
def __slot_btn_delete_label__(self):
|
||
if self.pressed_number is not None:
|
||
self.data.df_Artifact_a = self.data.df_Artifact_a[self.data.df_Artifact_a['number'] != self.pressed_number]
|
||
self.data.df_Artifact_a = self.data.df_Artifact_a.reset_index(drop=True)
|
||
sorted_part = self.data.df_Artifact_a[['type', 'startTime', 'endTime']].sort_values(by='startTime').reset_index(
|
||
drop=True)
|
||
self.data.df_Artifact_a[['type', 'startTime', 'endTime']] = sorted_part
|
||
self.data.df_Artifact_a['number'] = self.data.df_Artifact_a.index + 1
|
||
try:
|
||
if self.annotation_tableWidget:
|
||
self.annotation_tableWidget.remove()
|
||
except AttributeError:
|
||
pass
|
||
self.annotation_tableWidget = None
|
||
self.reset_labelBtn_color()
|
||
self.update_tableWidget()
|
||
self.update_Info()
|
||
self.__plot_artifact__()
|
||
self.save()
|
||
PublicFunc.text_output(self.ui, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY}", Constants.TIPS_TYPE_INFO)
|
||
else:
|
||
PublicFunc.text_output(self.ui, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE}", Constants.TIPS_TYPE_ERROR)
|
||
PublicFunc.msgbox_output(self, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE}", Constants.MSGBOX_TYPE_ERROR)
|
||
self.pressed_number = None
|
||
|
||
def __slot_btn_move__(self):
|
||
if self.data is None:
|
||
return
|
||
|
||
sender = self.sender()
|
||
|
||
if sender == self.ui.pushButton_prev_move:
|
||
Config["AutoplayArgs"]["AutoplayMode"] = "prev"
|
||
self.autoplay_xlim_start = int(self.ax0.get_xlim()[1] - Config["AutoplayArgs"]["MaxRange"])
|
||
self.autoplay_xlim_end = int(self.ax0.get_xlim()[1])
|
||
if self.autoplay_xlim_end > len(self.data.BCG):
|
||
self.autoplay_xlim_start = int(len(self.data.BCG) - Config["AutoplayArgs"]["MaxRange"])
|
||
self.autoplay_xlim_end = int(len(self.data.BCG))
|
||
self.ax0.set_xlim(self.autoplay_xlim_start, self.autoplay_xlim_end)
|
||
self.canvas.draw()
|
||
self.timer_autoplay.start(Config["AutoplayArgs"]["MoveSpeed"])
|
||
PublicFunc.text_output(self.ui, Constants.ARTIFACT_LABEL_PREV_MOVE, Constants.TIPS_TYPE_INFO)
|
||
elif sender == self.ui.pushButton_next_move:
|
||
Config["AutoplayArgs"]["AutoplayMode"] = "next"
|
||
self.autoplay_xlim_start = int(self.ax0.get_xlim()[0])
|
||
self.autoplay_xlim_end = int(self.ax0.get_xlim()[0] + Config["AutoplayArgs"]["MaxRange"])
|
||
if self.autoplay_xlim_start < 0:
|
||
self.autoplay_xlim_start = 0
|
||
self.autoplay_xlim_end = 0 + Config["AutoplayArgs"]["MaxRange"]
|
||
self.ax0.set_xlim(self.autoplay_xlim_start, self.autoplay_xlim_end)
|
||
self.canvas.draw()
|
||
self.timer_autoplay.start(Config["AutoplayArgs"]["MoveSpeed"])
|
||
PublicFunc.text_output(self.ui, Constants.ARTIFACT_LABEL_NEXT_MOVE, Constants.TIPS_TYPE_INFO)
|
||
elif sender == self.ui.pushButton_pause:
|
||
Config["AutoplayArgs"]["AutoplayMode"] = "pause"
|
||
self.timer_autoplay.stop()
|
||
PublicFunc.text_output(self.ui, Constants.ARTIFACT_LABEL_PAUSE, Constants.TIPS_TYPE_INFO)
|
||
|
||
def __change_autoplay_args__(self):
|
||
sender = self.sender()
|
||
|
||
if sender == self.ui.radioButton_move_preset_1 and self.ui.radioButton_move_preset_1.isChecked():
|
||
Config["AutoplayArgs"]["MoveLength"] = int(self.ui.label_moveLength_preset_1.text())
|
||
Config["AutoplayArgs"]["MaxRange"] = int(self.ui.label_maxRange_preset_1.text())
|
||
Config["AutoplayArgs"]["MoveSpeed"] = int(self.ui.label_moveSpeed_preset_1.text())
|
||
PublicFunc.text_output(self.ui, Constants.ARTIFACT_LABEL_SWITCH_PRESET_1, Constants.TIPS_TYPE_INFO)
|
||
elif sender == self.ui.radioButton_move_preset_2 and self.ui.radioButton_move_preset_2.isChecked():
|
||
Config["AutoplayArgs"]["MoveLength"] = int(self.ui.label_moveLength_preset_2.text())
|
||
Config["AutoplayArgs"]["MaxRange"] = int(self.ui.label_maxRange_preset_2.text())
|
||
Config["AutoplayArgs"]["MoveSpeed"] = int(self.ui.label_moveSpeed_preset_2.text())
|
||
PublicFunc.text_output(self.ui, Constants.ARTIFACT_LABEL_SWITCH_PRESET_2, Constants.TIPS_TYPE_INFO)
|
||
elif sender == self.ui.radioButton_move_preset_3 and self.ui.radioButton_move_preset_3.isChecked():
|
||
Config["AutoplayArgs"]["MoveLength"] = int(self.ui.label_moveLength_preset_3.text())
|
||
Config["AutoplayArgs"]["MaxRange"] = int(self.ui.label_maxRange_preset_3.text())
|
||
Config["AutoplayArgs"]["MoveSpeed"] = int(self.ui.label_moveSpeed_preset_3.text())
|
||
PublicFunc.text_output(self.ui, Constants.ARTIFACT_LABEL_SWITCH_PRESET_3, Constants.TIPS_TYPE_INFO)
|
||
elif sender == self.ui.radioButton_move_custom and self.ui.radioButton_move_custom.isChecked():
|
||
Config["AutoplayArgs"]["MoveLength"] = int(self.ui.spinBox_moveLength.value())
|
||
Config["AutoplayArgs"]["MaxRange"] = int(self.ui.spinBox_maxRange.value())
|
||
Config["AutoplayArgs"]["MoveSpeed"] = int(self.ui.spinBox_moveSpeed.value())
|
||
PublicFunc.text_output(self.ui, Constants.ARTIFACT_LABEL_SWITCH_CUSTOM, Constants.TIPS_TYPE_INFO)
|
||
if Config["AutoplayArgs"]["AutoplayMode"] == "next":
|
||
self.autoplay_xlim_start = int(self.ax0.get_xlim()[0])
|
||
self.autoplay_xlim_end = int(self.ax0.get_xlim()[0] + Config["AutoplayArgs"]["MaxRange"])
|
||
if self.autoplay_xlim_start < 0:
|
||
self.autoplay_xlim_start = 0
|
||
self.autoplay_xlim_end = 0 + Config["AutoplayArgs"]["MaxRange"]
|
||
self.ax0.set_xlim(self.autoplay_xlim_start, self.autoplay_xlim_end)
|
||
self.timer_autoplay.start(Config["AutoplayArgs"]["MoveSpeed"])
|
||
elif Config["AutoplayArgs"]["AutoplayMode"] == "prev":
|
||
self.autoplay_xlim_start = int(self.ax0.get_xlim()[1] - Config["AutoplayArgs"]["MaxRange"])
|
||
self.autoplay_xlim_end = int(self.ax0.get_xlim()[1])
|
||
if self.autoplay_xlim_end > len(self.data.BCG):
|
||
self.autoplay_xlim_start = int(self.data.BCG) - Config["AutoplayArgs"]["MaxRange"]
|
||
self.autoplay_xlim_end = int(self.data.BCG)
|
||
self.ax0.set_xlim(self.autoplay_xlim_start, self.autoplay_xlim_end)
|
||
self.timer_autoplay.start(Config["AutoplayArgs"]["MoveSpeed"])
|
||
elif Config["AutoplayArgs"]["AutoplayMode"] == "pause":
|
||
self.timer_autoplay.stop()
|
||
|
||
def __slot_tableWidget_on_cell_double_clicked__(self, row, col):
|
||
if Config["AutoplayArgs"]["AutoplayMode"] != "pause":
|
||
self.ui.pushButton_pause.click()
|
||
|
||
sender = self.sender()
|
||
|
||
if sender == self.ui.tableWidget_type_1:
|
||
self.pressed_number = int(
|
||
self.ui.tableWidget_type_1.item(row, 0).text())
|
||
startTime = int(self.ui.tableWidget_type_1.item(row, 1).text())
|
||
endTime = int(self.ui.tableWidget_type_1.item(row, 2).text())
|
||
type = 1
|
||
elif sender == self.ui.tableWidget_type_2:
|
||
self.pressed_number = int(
|
||
self.ui.tableWidget_type_2.item(row, 0).text())
|
||
startTime = int(self.ui.tableWidget_type_2.item(row, 1).text())
|
||
endTime = int(self.ui.tableWidget_type_2.item(row, 2).text())
|
||
type = 2
|
||
elif sender == self.ui.tableWidget_type_3:
|
||
self.pressed_number = int(
|
||
self.ui.tableWidget_type_3.item(row, 0).text())
|
||
startTime = int(self.ui.tableWidget_type_3.item(row, 1).text())
|
||
endTime = int(self.ui.tableWidget_type_3.item(row, 2).text())
|
||
type = 3
|
||
elif sender == self.ui.tableWidget_type_4:
|
||
self.pressed_number = int(
|
||
self.ui.tableWidget_type_4.item(row, 0).text())
|
||
startTime = int(self.ui.tableWidget_type_4.item(row, 1).text())
|
||
endTime = int(self.ui.tableWidget_type_4.item(row, 2).text())
|
||
type = 4
|
||
elif sender == self.ui.tableWidget_type_5:
|
||
self.pressed_number = int(
|
||
self.ui.tableWidget_type_5.item(row, 0).text())
|
||
startTime = int(self.ui.tableWidget_type_5.item(row, 1).text())
|
||
endTime = int(self.ui.tableWidget_type_5.item(row, 2).text())
|
||
type = 5
|
||
else:
|
||
raise ValueError()
|
||
|
||
self.ax0.set_xlim(startTime - 60000, endTime + 60000)
|
||
self.annotation_tableWidget = self.ax0.annotate(f'number={int(self.pressed_number)}, duration={int(endTime - startTime)}ms',
|
||
xy=(int(startTime + (endTime - startTime) / 2), self.ax0.get_ylim()[0]),
|
||
xytext=(
|
||
int(startTime + (endTime - startTime) / 2), self.ax0.get_ylim()[0] + (
|
||
self.ax0.get_ylim()[1] - self.ax0.get_ylim()[
|
||
0]) * 0.1),
|
||
arrowprops=dict(facecolor=Constants.PLOT_COLOR_BLACK, shrink=0.1))
|
||
self.change_labelBtn_color(type)
|
||
self.ui.pushButton_delete.setEnabled(True)
|
||
self.canvas.draw()
|
||
self.rect_left = startTime
|
||
self.rect_right = endTime
|
||
self.update_label_args(int(self.rect_left), int(self.rect_right))
|
||
PublicFunc.text_output(self.ui, f"{Constants.ARTIFACT_LABEL_JUMP_ARTIFACT}{str(self.pressed_number)}", Constants.TIPS_TYPE_INFO)
|
||
|
||
def reset_axes(self):
|
||
if self.ax0 is not None:
|
||
self.ax0.clear()
|
||
self.ax0.grid(True)
|
||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||
if self.ax1 is not None:
|
||
self.ax1.clear()
|
||
self.ax1.grid(True)
|
||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||
|
||
def on_xlim_change(self, event_ax):
|
||
try:
|
||
if self.annotation_tableWidget:
|
||
self.annotation_tableWidget.remove()
|
||
except AttributeError:
|
||
pass
|
||
self.annotation_tableWidget = None
|
||
self.reset_labelBtn_color()
|
||
ButtonState["Current"]["pushButton_delete"] = False
|
||
PublicFunc.__enableAllButton__(self, ButtonState)
|
||
|
||
def autoplay_move_xlim(self):
|
||
if Config["AutoplayArgs"]["AutoplayMode"] == "prev" and self.autoplay_xlim_start < 0:
|
||
Config["AutoplayArgs"]["AutoplayMode"] = "pause"
|
||
self.timer_autoplay.stop()
|
||
elif Config["AutoplayArgs"]["AutoplayMode"] == "next" and self.autoplay_xlim_end > len(self.data.BCG):
|
||
Config["AutoplayArgs"]["AutoplayMode"] = "pause"
|
||
self.timer_autoplay.stop()
|
||
else:
|
||
if Config["AutoplayArgs"]["AutoplayMode"] == "next":
|
||
self.autoplay_xlim_start += Config["AutoplayArgs"]["MoveLength"]
|
||
self.autoplay_xlim_end += Config["AutoplayArgs"]["MoveLength"]
|
||
elif Config["AutoplayArgs"]["AutoplayMode"] == "prev":
|
||
self.autoplay_xlim_start -= Config["AutoplayArgs"]["MoveLength"]
|
||
self.autoplay_xlim_end -= Config["AutoplayArgs"]["MoveLength"]
|
||
self.ax0.set_xlim(self.autoplay_xlim_start, self.autoplay_xlim_end)
|
||
self.canvas.draw()
|
||
|
||
def change_labelBtn_color(self, type):
|
||
if type == 1:
|
||
self.ui.pushButton_type_1.setStyleSheet(
|
||
Constants.ARTIFACT_LABEL_LABELBTN_STYLE_1)
|
||
self.ui.pushButton_type_2.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_3.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_4.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_5.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
elif type == 2:
|
||
self.ui.pushButton_type_1.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_2.setStyleSheet(
|
||
Constants.ARTIFACT_LABEL_LABELBTN_STYLE_2)
|
||
self.ui.pushButton_type_3.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_4.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_5.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
elif type == 3:
|
||
self.ui.pushButton_type_1.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_2.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_3.setStyleSheet(
|
||
Constants.ARTIFACT_LABEL_LABELBTN_STYLE_3)
|
||
self.ui.pushButton_type_4.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_5.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
elif type == 4:
|
||
self.ui.pushButton_type_1.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_2.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_3.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_4.setStyleSheet(
|
||
Constants.ARTIFACT_LABEL_LABELBTN_STYLE_4)
|
||
self.ui.pushButton_type_5.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
elif type == 5:
|
||
self.ui.pushButton_type_1.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_2.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_3.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_4.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_5.setStyleSheet(
|
||
Constants.ARTIFACT_LABEL_LABELBTN_STYLE_5)
|
||
|
||
def reset_labelBtn_color(self):
|
||
self.ui.pushButton_type_1.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_2.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_3.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_4.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
self.ui.pushButton_type_5.setStyleSheet(Constants.STRING_IS_EMPTY)
|
||
|
||
def toggle_home(self):
|
||
if Config["AutoplayArgs"]["AutoplayMode"] != "pause":
|
||
self.ui.pushButton_pause.click()
|
||
if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None:
|
||
self.figToolbar.rect_patch_ax0.remove()
|
||
self.figToolbar.rect_patch_ax0 = None
|
||
self.figToolbar.rect_patch_ax1.remove()
|
||
self.figToolbar.rect_patch_ax1 = None
|
||
self.rect_left = None
|
||
self.rect_right = None
|
||
self.ui.lineEdit_start_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_end_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_duration.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_orgBcg.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_BCG.setText(Constants.STRING_IS_EMPTY)
|
||
self.canvas.draw()
|
||
self.ax0.autoscale(True)
|
||
self.ax1.autoscale(True)
|
||
self.ax1.relim()
|
||
self.ax1.autoscale_view()
|
||
self.canvas.draw()
|
||
self.ax0.autoscale(False)
|
||
self.ax1.autoscale(False)
|
||
PublicFunc.text_output(self.ui, Constants.ARTIFACT_LABEL_RECOVER_SCALE, Constants.TIPS_TYPE_INFO)
|
||
|
||
def toggle_zoom(self):
|
||
if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None:
|
||
self.figToolbar.rect_patch_ax0.remove()
|
||
self.figToolbar.rect_patch_ax0 = None
|
||
self.figToolbar.rect_patch_ax1.remove()
|
||
self.figToolbar.rect_patch_ax1 = None
|
||
self.rect_left = None
|
||
self.rect_right = None
|
||
self.ui.lineEdit_start_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_end_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_duration.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_orgBcg.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_BCG.setText(Constants.STRING_IS_EMPTY)
|
||
self.canvas.draw()
|
||
|
||
def toggle_pan(self):
|
||
if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None:
|
||
self.figToolbar.rect_patch_ax0.remove()
|
||
self.figToolbar.rect_patch_ax0 = None
|
||
self.figToolbar.rect_patch_ax1.remove()
|
||
self.figToolbar.rect_patch_ax1 = None
|
||
self.rect_left = None
|
||
self.rect_right = None
|
||
self.ui.lineEdit_start_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_end_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_duration.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_orgBcg.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_BCG.setText(Constants.STRING_IS_EMPTY)
|
||
self.canvas.draw()
|
||
|
||
def toggle_label_artifact(self, state):
|
||
if state:
|
||
self.deactivate_figToolbar_buttons()
|
||
self.figToolbar.action_Label_Artifact.setChecked(True)
|
||
self.figToolbar.cid_mouse_press = self.canvas.mpl_connect(
|
||
"button_press_event", self.on_click)
|
||
self.figToolbar.cid_mouse_release = self.canvas.mpl_connect(
|
||
"button_release_event", self.on_release)
|
||
self.figToolbar.cid_mouse_hold = self.canvas.mpl_connect(
|
||
"motion_notify_event", self.on_hold)
|
||
else:
|
||
if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None:
|
||
self.figToolbar.rect_patch_ax0.remove()
|
||
self.figToolbar.rect_patch_ax0 = None
|
||
self.figToolbar.rect_patch_ax1.remove()
|
||
self.figToolbar.rect_patch_ax1 = None
|
||
self.rect_left = None
|
||
self.rect_right = None
|
||
self.ui.lineEdit_start_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_end_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_duration.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_orgBcg.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_BCG.setText(Constants.STRING_IS_EMPTY)
|
||
self.canvas.draw()
|
||
if self.figToolbar.cid_mouse_press is not None:
|
||
self.canvas.mpl_disconnect(self.figToolbar.cid_mouse_press)
|
||
self.figToolbar.cid_mouse_press = None
|
||
if self.figToolbar.cid_mouse_release is not None:
|
||
self.canvas.mpl_disconnect(self.figToolbar.cid_mouse_release)
|
||
self.figToolbar.cid_mouse_release = None
|
||
if self.figToolbar.cid_mouse_hold:
|
||
self.canvas.mpl_disconnect(self.figToolbar.cid_mouse_hold)
|
||
self.figToolbar.cid_mouse_hold = None
|
||
|
||
def deactivate_figToolbar_buttons(self):
|
||
for action in self.figToolbar._actions.values():
|
||
if action.isChecked():
|
||
if action == self.figToolbar._actions['pan']:
|
||
self.figToolbar.pan()
|
||
if action == self.figToolbar._actions['zoom']:
|
||
self.figToolbar.zoom()
|
||
|
||
def on_click(self, event):
|
||
if self.figToolbar.action_Label_Artifact.isChecked():
|
||
self.reset_labelBtn_color()
|
||
ButtonState["Current"]["pushButton_delete"] = False
|
||
PublicFunc.__enableAllButton__(self, ButtonState)
|
||
if event.button == 1:
|
||
self.is_left_button_pressed = True
|
||
self.figToolbar.rect_start_x = event.xdata
|
||
# 如果矩形patch已存在,先移除
|
||
if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None:
|
||
self.figToolbar.rect_patch_ax0.remove()
|
||
self.figToolbar.rect_patch_ax0 = None
|
||
self.figToolbar.rect_patch_ax1.remove()
|
||
self.figToolbar.rect_patch_ax1 = None
|
||
self.rect_left = None
|
||
self.rect_right = None
|
||
self.ui.lineEdit_start_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_end_time.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_duration.setText(Constants.STRING_IS_EMPTY)
|
||
self.canvas.draw()
|
||
self.ui.lineEdit_energy_percent_orgBcg.setText(Constants.STRING_IS_EMPTY)
|
||
self.ui.lineEdit_energy_percent_BCG.setText(Constants.STRING_IS_EMPTY)
|
||
|
||
def on_release(self, event):
|
||
if self.figToolbar.rect_start_x is not None:
|
||
self.figToolbar.rect_end_x = event.xdata
|
||
if self.figToolbar.rect_start_x is not None and self.figToolbar.rect_end_x is not None:
|
||
if self.figToolbar.rect_start_x < self.figToolbar.rect_end_x:
|
||
self.rect_left = self.figToolbar.rect_start_x
|
||
self.rect_right = self.figToolbar.rect_end_x
|
||
elif self.figToolbar.rect_start_x > self.figToolbar.rect_end_x:
|
||
self.rect_left = self.figToolbar.rect_end_x
|
||
self.rect_right = self.figToolbar.rect_start_x
|
||
else:
|
||
self.rect_left = self.figToolbar.rect_start_x
|
||
self.rect_right = self.figToolbar.rect_start_x
|
||
else:
|
||
self.rect_left = self.figToolbar.rect_start_x
|
||
self.rect_right = self.figToolbar.rect_start_x
|
||
if event.button == 1 and self.is_left_button_pressed:
|
||
self.is_left_button_pressed = False
|
||
if self.rect_left < 0:
|
||
self.rect_left = 0
|
||
elif self.rect_left >= len(self.data.BCG):
|
||
self.rect_left = 0
|
||
self.rect_right = 0
|
||
if self.rect_right >= len(self.data.BCG):
|
||
self.rect_right = len(self.data.BCG) - 1
|
||
elif self.rect_right < 0:
|
||
self.rect_left = 0
|
||
self.rect_right = 0
|
||
|
||
if int(self.rect_left) != int(self.rect_right):
|
||
self.update_label_args(int(self.rect_left), int(self.rect_right))
|
||
|
||
self.figToolbar.rect_start_x = None
|
||
self.figToolbar.rect_end_x = None
|
||
self.canvas.draw()
|
||
|
||
def on_hold(self, event):
|
||
if self.figToolbar.rect_start_x is not None and event.xdata is not None:
|
||
self.figToolbar.rect_end_x = event.xdata
|
||
|
||
# 如果矩形patch不存在,则创建一个新的
|
||
if self.figToolbar.rect_patch_ax0 is None:
|
||
if self.is_left_button_pressed:
|
||
self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True, alpha=0.2, color='r')
|
||
self.ax0.add_patch(self.figToolbar.rect_patch_ax0)
|
||
|
||
# 如果矩形patch不存在,则创建一个新的
|
||
if self.figToolbar.rect_patch_ax1 is None:
|
||
if self.is_left_button_pressed:
|
||
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True, alpha=0.2, color='r')
|
||
self.ax1.add_patch(self.figToolbar.rect_patch_ax1)
|
||
|
||
# 更新矩形patch的位置和大小
|
||
x_start = self.figToolbar.rect_start_x
|
||
x_end = self.figToolbar.rect_end_x
|
||
self.figToolbar.rect_patch_ax0.set_xy((min(x_start, x_end), self.rect_down))
|
||
self.figToolbar.rect_patch_ax0.set_width(abs(x_end - x_start))
|
||
self.figToolbar.rect_patch_ax0.set_height(self.rect_up - self.rect_down)
|
||
self.figToolbar.rect_patch_ax1.set_xy((min(x_start, x_end), self.rect_down))
|
||
self.figToolbar.rect_patch_ax1.set_width(abs(x_end - x_start))
|
||
self.figToolbar.rect_patch_ax1.set_height(self.rect_up - self.rect_down)
|
||
|
||
self.canvas.draw()
|
||
|
||
|
||
class Data:
|
||
|
||
def __init__(self):
|
||
self.orgBcg = None
|
||
self.BCG = None
|
||
self.Artifact_a = None
|
||
self.df_Artifact_a = DataFrame(columns=["number", "type", "startTime", "endTime"])
|
||
|
||
def open_file(self):
|
||
if Path(Config["Path"]["Input_orgBcg"]).is_file():
|
||
Config["Path"]["Input_orgBcg"] = str(Path(Config["Path"]["Input_orgBcg"]).parent)
|
||
if Path(Config["Path"]["Input_BCG"]).is_file():
|
||
Config["Path"]["Input_BCG"] = str(Path(Config["Path"]["Input_BCG"]).parent)
|
||
|
||
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
|
||
if result.status:
|
||
Config["Path"]["Input_orgBcg"] = result.data["path"]
|
||
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
|
||
else:
|
||
return result
|
||
|
||
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_SYNC, Params.ENDSWITH_TXT)
|
||
if result.status:
|
||
Config["Path"]["Input_BCG"] = result.data["path"]
|
||
Config["InputConfig"]["BCGFreq"] = result.data["freq"]
|
||
else:
|
||
return result
|
||
|
||
Config["Path"]["Save_a"] = str(
|
||
Path(Config["Path"]["Save_a"]) / Path(Filename.ARTIFACT_A + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_TXT))
|
||
Config["Path"]["Save_b"] = str(
|
||
Path(Config["Path"]["Save_b"]) / Path(Filename.ARTIFACT_B + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_TXT))
|
||
Config["Path"]["Save_c"] = str(
|
||
Path(Config["Path"]["Save_c"]) / Path(Filename.ARTIFACT_C + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_CSV))
|
||
|
||
try:
|
||
self.orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
|
||
encoding=Params.UTF8_ENCODING,
|
||
header=None).to_numpy().reshape(-1)
|
||
self.BCG = read_csv(Config["Path"]["Input_BCG"],
|
||
encoding=Params.UTF8_ENCODING,
|
||
header=None).to_numpy().reshape(-1)
|
||
except Exception as e:
|
||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
|
||
|
||
# 检查同步后的orgBcg信号和同步后的BCG信号长度是否相同
|
||
if len(self.orgBcg) != len(self.BCG):
|
||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Data_Length_not_Correct"])
|
||
|
||
return Result().success(info=Constants.INPUT_FINISHED)
|
||
|
||
def resample(self):
|
||
if self.orgBcg is None:
|
||
return Result().failure(info=Constants.RESAMPLE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||
|
||
try:
|
||
if Config["InputConfig"]["orgBcgFreq"] != Config["InputConfig"]["UseFreq"]:
|
||
self.orgBcg = resample(self.orgBcg,
|
||
int(len(self.orgBcg) *
|
||
(Config["InputConfig"]["UseFreq"] / Config["InputConfig"]["orgBcgFreq"])))
|
||
else:
|
||
return Result().success(info=Constants.RESAMPLE_NO_NEED)
|
||
except Exception as e:
|
||
return Result().failure(info=Constants.RESAMPLE_FAILURE +
|
||
Constants.FAILURE_REASON["Resample_Exception"] + "\n" + format_exc())
|
||
|
||
return Result().success(info=Constants.RESAMPLE_FINISHED)
|
||
|
||
def get_archive(self):
|
||
if not Path(Config["Path"]["Save_a"]).exists():
|
||
self.Artifact_a = []
|
||
return Result().success(info=Constants.ARCHIVE_NOT_EXIST)
|
||
else:
|
||
self.Artifact_a = read_csv(Config["Path"]["Save_a"],
|
||
encoding=Params.UTF8_ENCODING,
|
||
header=None).to_numpy().reshape(-1)
|
||
try:
|
||
# 检查体动标签正确性,长度
|
||
if len(self.Artifact_a) % 4 != 0:
|
||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON[
|
||
"Artifact_Format_Not_Correct"])
|
||
for i in range(0, len(self.Artifact_a), 4):
|
||
unit_data = self.Artifact_a[i:i + 4]
|
||
if len(unit_data) < 4:
|
||
break
|
||
self.df_Artifact_a.loc[len(self.df_Artifact_a)] = [int(unit_data[j]) for j in range(4)]
|
||
except Exception as e:
|
||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON[
|
||
"Get_Artifact_Format_Exception"] + "\n" + format_exc())
|
||
|
||
return Result().success(info=Constants.ARCHIVE_EXIST)
|
||
|
||
def save(self, amount, duration):
|
||
try:
|
||
# Artifact_a.txt和Artifact_c.csv的内容遍历
|
||
output_lines = []
|
||
for row_index in range(len(self.df_Artifact_a)):
|
||
for col in self.df_Artifact_a.columns:
|
||
value = self.df_Artifact_a.at[row_index, col]
|
||
output_lines.append(str(value))
|
||
|
||
# Artifact_b.txt的内容遍历
|
||
dict = {
|
||
'type': [1, 2, 3, 4, 5],
|
||
'amount': [int(amount[0]), int(amount[1]), int(amount[2]), int(amount[3]), int(amount[4])],
|
||
'duration': [int(duration[0]), int(duration[1]), int(duration[2]), int(duration[3]), int(duration[4])]
|
||
}
|
||
df_Artifact_b = DataFrame(dict)
|
||
|
||
# 写入文件并保存
|
||
self.df_Artifact_a.to_csv(Path(Config["Path"]["Save_a"]), header=False, index=False, sep='\n')
|
||
df_Artifact_b.to_csv(Path(Config["Path"]["Save_b"]), header=False, index=False, sep='\n')
|
||
self.df_Artifact_a.to_csv(Path(Config["Path"]["Save_c"]), index=False,
|
||
encoding=Params.GBK_ENCODING)
|
||
except PermissionError as e:
|
||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_Permission_Denied"])
|
||
except FileNotFoundError as e:
|
||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_File_Not_Found"])
|
||
except Exception as e:
|
||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON[
|
||
"Save_Exception"] + "\n" + format_exc())
|
||
|
||
return Result().success(info=Constants.SAVE_FINISHED)
|
||
|
||
|
||
class CustomNavigationToolbar(NavigationToolbar2QT):
|
||
|
||
def __init__(self, canvas, parent):
|
||
super().__init__(canvas, parent)
|
||
# 初始化画框工具栏
|
||
self.action_Label_Artifact = QAction(Constants.ARTIFACT_LABEL_ACTION_LABEL, self)
|
||
self.action_Label_Artifact.setFont(QFont(Params.FONT, 14))
|
||
self.action_Label_Artifact.setCheckable(True)
|
||
self.action_Label_Artifact.setShortcut(QCoreApplication.translate(
|
||
"MainWindow",
|
||
Params.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY))
|
||
self.insertAction(self._actions['pan'], self.action_Label_Artifact)
|
||
|
||
self._actions['pan'].setShortcut(QCoreApplication.translate(
|
||
"MainWindow",
|
||
Params.ACTION_PAN_SHORTCUT_KEY))
|
||
self._actions['zoom'].setShortcut(QCoreApplication.translate(
|
||
"MainWindow",
|
||
Params.ACTION_ZOOM_SHORTCUT_KEY))
|
||
|
||
# 用于存储事件连接ID
|
||
self.cid_mouse_press = None
|
||
self.cid_mouse_release = None
|
||
self.cid_mouse_hold = None
|
||
|
||
# 初始化矩形选择区域
|
||
self.rect_start_x = None
|
||
self.rect_end_x = None
|
||
self.rect_patch_ax0 = None # 用于绘制矩形的patch
|
||
self.rect_patch_ax1 = None # 用于绘制矩形的patch
|
||
|
||
def home(self, *args):
|
||
pass
|
||
|
||
def zoom(self, *args):
|
||
super().zoom(*args)
|
||
self.deactivate_figToorbar_label_artifact()
|
||
|
||
def pan(self, *args):
|
||
super().pan(*args)
|
||
self.deactivate_figToorbar_label_artifact()
|
||
|
||
def deactivate_figToorbar_label_artifact(self):
|
||
if self.action_Label_Artifact.isChecked():
|
||
self.action_Label_Artifact.setChecked(False)
|
||
if self.cid_mouse_press is not None:
|
||
self.canvas.mpl_disconnect(self.cid_mouse_press)
|
||
self.cid_mouse_press = None
|
||
if self.cid_mouse_release is not None:
|
||
self.canvas.mpl_disconnect(self.cid_mouse_release)
|
||
self.cid_mouse_release = None |