Files
Signal_Label_Reborn/func/Module_artifact_label.py

1594 lines
83 KiB
Python
Raw 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.

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