1、完成<数据粗同步>的全部功能

2、将业务返回结果封装成了一个Result对象
This commit is contained in:
2025-05-10 19:45:57 +08:00
parent 2bd2a1843f
commit b9f9122a65
22 changed files with 3821 additions and 549 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@ from yaml import dump, load, FullLoader
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Result import Result
from ui.MainWindow.MainWindow_cut_PSG import Ui_MainWindow_cut_PSG
@ -73,19 +74,22 @@ class MainWindow_cut_PSG(QMainWindow):
@overrides
def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState)
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()
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
QApplication.processEvents()
# 释放资源
del self.data
self.deleteLater()
collect()
event.accept()
# 释放资源
del self.data
self.deleteLater()
collect()
event.accept()
else:
event.ignore()
@staticmethod
def __reset__():
def __reset__(self):
ButtonState["Current"].update(ButtonState["Default"].copy())
def __read_config__(self):
@ -108,68 +112,73 @@ class MainWindow_cut_PSG(QMainWindow):
# 检查文件是否存在并获取其数据采样率
PublicFunc.progressbar_update(self, 1, 5, Constants.CUT_PSG_GETTING_FILE_AND_FREQ, 0)
status, info = self.data.get_file_and_freq()
if not status:
PublicFunc.text_output(self.ui, "(1/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.get_file_and_freq()
if not result.status:
PublicFunc.text_output(self.ui, "(1/5)" + 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/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/5)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
# 导入数据
PublicFunc.progressbar_update(self, 2, 5, Constants.INPUTTING_DATA, 10)
status, info = self.data.open_file()
if not status:
PublicFunc.text_output(self.ui, "(2/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.open_file()
if not result.status:
PublicFunc.text_output(self.ui, "(2/5)" + 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/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/5)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
# 切割数据
PublicFunc.progressbar_update(self, 3, 5, Constants.CUT_PSG_CUTTING_DATA, 40)
status, info = self.data.cut_data()
if not status:
PublicFunc.text_output(self.ui, "(3/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.cut_data()
if not result.status:
PublicFunc.text_output(self.ui, "(3/5)" + 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/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(3/5)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
# 标签映射
PublicFunc.progressbar_update(self, 4, 5, Constants.CUT_PSG_ALIGNING_LABEL, 60)
status, info = self.data.align_label()
if not status:
PublicFunc.text_output(self.ui, "(4/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.align_label()
if not result.status:
PublicFunc.text_output(self.ui, "(4/5)" + 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/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(4/5)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
# 切割数据
# 保存数据
PublicFunc.progressbar_update(self, 5, 5, Constants.SAVING_DATA, 70)
status, info = self.data.save()
if not status:
PublicFunc.text_output(self.ui, "(5/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.save()
if not result.status:
PublicFunc.text_output(self.ui, "(5/5)" + 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/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(5/5)" + result.info, Constants.TIPS_TYPE_INFO)
for key, raw in self.data.raw.items():
info = "保存{}的长度为{},采样率为{}Hz".format(key, str(len(raw)), str(self.data.freq[key]))
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
QApplication.processEvents()
PublicFunc.msgbox_output(self, result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
@ -196,20 +205,20 @@ class Data:
freq = int(freq_str)
self.freq[key] = freq
except ValueError:
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Filename_Format_not_Correct"]
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Filename_Format_not_Correct"])
for value in self.freq.values():
if value == 0:
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Filename_Format_not_Correct"]
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Filename_Format_not_Correct"])
if not any((Config["LabelInput"]["SA Label"] + Config["EndWith"]["SA Label"]) in str(file) for file in Path(Config["Path"]["InputFolder"]).glob('*')):
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"]
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"])
if not any((Config["StartTime"] + Config["EndWith"]["StartTime"]) in str(file) for file in Path(Config["Path"]["InputFolder"]).glob('*')):
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"]
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"])
if not Path(Config["Path"]["InputAlignInfo"]).exists():
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"]
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"])
except Exception:
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE["Get_File_and_Freq_Excepetion"]
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE["Get_File_and_Freq_Excepetion"])
return True, Constants.CUT_PSG_GET_FILE_AND_FREQ_FINISHED
return Result().success(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FINISHED)
def open_file(self):
try:
@ -227,9 +236,9 @@ class Data:
header=None).to_numpy().reshape(-1)
self.alignInfo = literal_eval(self.alignInfo[0])
except Exception:
return False, Constants.INPUT_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Read_Data_Exception"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Read_Data_Exception"])
return True, Constants.INPUT_FINISHED
return Result().success(info=Constants.INPUT_FINISHED)
def cut_data(self):
try:
@ -245,11 +254,11 @@ class Data:
# 切割信号
self.raw[key] = self.raw[key][start_index_cut:end_index_cut]
except Exception:
return False, Constants.CUT_PSG_CUT_DATA_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Cut_Data_Length_not_Correct"]
return Result().failure(info=Constants.CUT_PSG_CUT_DATA_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Cut_Data_Length_not_Correct"])
except Exception:
return False, Constants.CUT_PSG_CUT_DATA_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Cut_Data_Exception"]
return Result().failure(info=Constants.CUT_PSG_CUT_DATA_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Cut_Data_Exception"])
return True, Constants.CUT_PSG_CUT_DATA_FINISHED
return Result().success(info=Constants.CUT_PSG_CUT_DATA_FINISHED)
def align_label(self):
try:
@ -259,7 +268,7 @@ class Data:
self.SALabel["Duration"] = self.SALabel["Duration"].astype(str)
self.SALabel["Duration"] = self.SALabel["Duration"].str.replace(r' \(.*?\)', '', regex=True)
except Exception:
return False, Constants.CUT_PSG_ALIGN_LABEL_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Align_Label_SALabel_Format_not_Correct"]
return Result().failure(info=Constants.CUT_PSG_ALIGN_LABEL_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Align_Label_SALabel_Format_not_Correct"])
try:
# 获取记录开始时间
@ -280,14 +289,14 @@ class Data:
self.SALabel = self.SALabel[self.SALabel["Start"] < ECG_length]
self.SALabel.loc[self.SALabel["End"] >= ECG_length, "End"] = ECG_length - 1
except Exception:
return False, Constants.CUT_PSG_ALIGN_LABEL_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Align_Label_Exception"]
return Result().failure(info=Constants.CUT_PSG_ALIGN_LABEL_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Align_Label_Exception"])
return True, Constants.CUT_PSG_ALIGN_LABEL_FINISHED
return Result().success(info=Constants.CUT_PSG_ALIGN_LABEL_FINISHED)
def save(self):
for raw in self.raw.values():
if len(raw) == 0:
return False, Constants.SAVING_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Save_Data_not_Exist"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Save_Data_not_Exist"])
try:
for key, raw in self.raw.items():
@ -297,9 +306,9 @@ class Data:
index=False,
encoding="gbk")
except Exception:
return False, Constants.SAVING_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Save_Exception"])
return True, Constants.SAVING_FINISHED
return Result().success(info=Constants.SAVING_FINISHED)
@staticmethod
def get_time_to_seconds(time_str):

View File

@ -12,6 +12,7 @@ from yaml import dump, load, FullLoader
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Result import Result
from func.utils.detect_Jpeak import preprocess, Jpeak_Detection
from ui.MainWindow.MainWindow_detect_Jpeak import Ui_MainWindow_detect_Jpeak
@ -190,26 +191,29 @@ class MainWindow_detect_Jpeak(QMainWindow):
@overrides
def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState)
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()
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
QApplication.processEvents()
# 清空画框
self.ax0.clear()
# 清空画框
self.ax0.clear()
# 释放资源
del self.data
del self.model
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
# 释放资源
del self.data
del self.model
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
else:
event.ignore()
@staticmethod
def __reset__():
def __reset__(self):
ButtonState["Current"].update(ButtonState["Default"].copy())
ButtonState["Current"]["pushButton_view"] = True
@ -230,14 +234,12 @@ class MainWindow_detect_Jpeak(QMainWindow):
color=Constants.PLOT_COLOR_ORANGE,
label=Constants.DETECT_JPEAK_PLOT_LABEL_INTERVAL)
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
status = True
info = Constants.DRAWING_FINISHED
else:
status = False
info = Constants.DRAWING_FAILURE
self.canvas.draw()
return status, info
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
else:
self.canvas.draw()
return Result().failure(info=Constants.DRAWING_FAILURE)
def __update_config__(self):
Config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value()
@ -264,28 +266,28 @@ class MainWindow_detect_Jpeak(QMainWindow):
# 寻找模型
PublicFunc.progressbar_update(self, 1, 2, Constants.DETECT_JPEAK_LOADING_MODEL, 0)
status, info = self.model.seek_model()
if not status:
PublicFunc.text_output(self.ui, "(1/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.model.seek_model()
if not result.status:
PublicFunc.text_output(self.ui, "(1/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/2)" + result.info, Constants.TIPS_TYPE_INFO)
self.update_ui_comboBox_model(self.model.model_list)
# 导入数据
PublicFunc.progressbar_update(self, 2, 2, Constants.INPUTTING_DATA, 10)
status, info = self.data.open_file()
if not status:
PublicFunc.text_output(self.ui, "(2/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.open_file()
if not result.status:
PublicFunc.text_output(self.ui, "(2/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/2)" + result.info, Constants.TIPS_TYPE_INFO)
MainWindow_detect_Jpeak.__reset__()
self.__reset__()
PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_view__(self):
@ -293,26 +295,26 @@ class MainWindow_detect_Jpeak(QMainWindow):
# 数据预处理
PublicFunc.progressbar_update(self, 1, 3, Constants.DETECT_JPEAK_PROCESSING_DATA, 0)
status, info = self.data.preprocess()
if not status:
PublicFunc.text_output(self.ui, "(1/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.preprocess()
if not result.status:
PublicFunc.text_output(self.ui, "(1/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/3)" + result.info, Constants.TIPS_TYPE_INFO)
# 预测峰值
PublicFunc.progressbar_update(self, 2, 3, Constants.DETECT_JPEAK_PREDICTING_PEAK, 10)
self.model.selected_model = Config["DetectMethod"]
status, info = self.data.predict_Jpeak(self.model)
if not status:
PublicFunc.text_output(self.ui, "(2/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.predict_Jpeak(self.model)
if not result.status:
PublicFunc.text_output(self.ui, "(2/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/3)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, Constants.DETECT_JPEAK_DATA_LENGTH_POINTS + str(len(self.data.raw_data)),
Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, Constants.DETECT_JPEAK_DURATION_MIN +
@ -323,14 +325,14 @@ class MainWindow_detect_Jpeak(QMainWindow):
# 绘图
PublicFunc.progressbar_update(self, 3, 3, Constants.DRAWING_DATA, 70)
status, info = self.__plot__()
if not status:
PublicFunc.text_output(self.ui, "(3/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.__plot__()
if not result.status:
PublicFunc.text_output(self.ui, "(3/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(3/3)" + result.info, Constants.TIPS_TYPE_INFO)
ButtonState["Current"]["pushButton_save"] = True
PublicFunc.finish_operation(self, ButtonState)
@ -352,20 +354,20 @@ class MainWindow_detect_Jpeak(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.peak.reshape(-1)).iloc[start:end]
status, info = self.data.save(chunk)
result = self.data.save(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(1/1)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, info, Constants.TIPS_TYPE_INFO)
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 reset_axes(self):
@ -388,20 +390,20 @@ class Data:
def open_file(self):
if not Path(Config["Path"]["Input"]).exists():
return False, Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Data_Path_Not_Exist"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Data_Path_Not_Exist"])
try:
self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception:
return False, Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Read_Data_Exception"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Read_Data_Exception"])
return True, Constants.INPUT_FINISHED
return Result().success(info=Constants.INPUT_FINISHED)
def preprocess(self):
if self.raw_data is None:
return False, Constants.DETECT_JPEAK_PROCESS_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Raw_Data_Not_Exist"]
return Result().failure(info=Constants.DETECT_JPEAK_PROCESS_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Raw_Data_Not_Exist"])
try:
self.processed_data = preprocess(self.raw_data,
@ -410,16 +412,16 @@ class Data:
Config["Filter"]["BandPassHigh"],
Config["AmpValue"])
except Exception:
return False, Constants.DETECT_JPEAK_PROCESS_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Filter_Exception"]
return Result().failure(info=Constants.DETECT_JPEAK_PROCESS_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Filter_Exception"])
return True, Constants.DETECT_JPEAK_PROCESS_FINISHED
return Result().success(info=Constants.DETECT_JPEAK_PROCESS_FINISHED)
def predict_Jpeak(self, model):
if not (Path(model.model_folder_path) / Path(model.selected_model)).exists():
return False, Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_File_Not_Exist"]
return Result().failure(info=Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_File_Not_Exist"])
if self.processed_data is None:
return False, Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Processed_Data_Not_Exist"]
return Result().failure(info=Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Processed_Data_Not_Exist"])
try:
self.peak, self.interval = Jpeak_Detection(model.selected_model,
@ -431,20 +433,20 @@ class Data:
Config["PeaksValue"],
Config["UseCPU"])
except Exception:
return False, Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Predict_Exception"]
return Result().failure(info=Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Predict_Exception"])
return True, Constants.DETECT_JPEAK_PREDICT_FINISHED
return Result().success(info=Constants.DETECT_JPEAK_PREDICT_FINISHED)
def save(self, chunk):
if self.peak is None:
return False, Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Peak_Not_Exist"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Peak_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False)
except Exception:
return False, Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Save_Exception"])
return True, Constants.SAVING_FINISHED
return Result().success(info=Constants.SAVING_FINISHED)
class Model:
@ -457,13 +459,13 @@ class Model:
def seek_model(self):
if not Path(Config["ModelFolderPath"]).exists():
return False, Constants.DETECT_JPEAK_LOAD_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_Path_Not_Exist"]
return Result().failure(info=Constants.DETECT_JPEAK_LOAD_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_Path_Not_Exist"])
try:
self.model_list = [file.name for file in Path(Config["ModelFolderPath"]).iterdir() if file.is_file()]
if len(self.model_list) == 0:
return False, Constants.DETECT_JPEAK_FAILURE_REASON["Model_File_Not_Exist"]
return Result().failure(info=Constants.DETECT_JPEAK_FAILURE_REASON["Model_File_Not_Exist"])
except Exception:
return False, Constants.DETECT_JPEAK_LOAD_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Read_Model_Exception"]
return Result().failure(info=Constants.DETECT_JPEAK_LOAD_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Read_Model_Exception"])
return True, Constants.DETECT_JPEAK_LOAD_FINISHED
return Result().success(info=Constants.DETECT_JPEAK_LOAD_FINISHED)

View File

@ -12,6 +12,7 @@ from yaml import dump, load, FullLoader
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Result import Result
from func.utils.detect_Rpeak import preprocess, Rpeak_Detection, get_method
from ui.MainWindow.MainWindow_detect_Rpeak import Ui_MainWindow_detect_Rpeak
@ -183,26 +184,29 @@ class MainWindow_detect_Rpeak(QMainWindow):
@overrides
def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState)
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()
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
QApplication.processEvents()
# 清空画框
self.ax0.clear()
self.ax1.clear()
# 清空画框
self.ax0.clear()
self.ax1.clear()
# 释放资源
del self.data
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
# 释放资源
del self.data
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
else:
event.ignore()
@staticmethod
def __reset__():
def __reset__(self):
ButtonState["Current"].update(ButtonState["Default"].copy())
ButtonState["Current"]["pushButton_view"] = True
@ -227,14 +231,11 @@ class MainWindow_detect_Rpeak(QMainWindow):
label=Constants.DETECT_RPEAK_PLOT_LABEL_INTERVAL)
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
self.ax1.legend(loc=Constants.PLOT_UPPER_RIGHT)
status = True
info = Constants.DRAWING_FINISHED
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
else:
status = False
info = Constants.DRAWING_FAILURE
self.canvas.draw()
return status, info
self.canvas.draw()
return Result().failure(info=Constants.DRAWING_FAILURE)
def __update_config__(self):
Config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value()
@ -259,32 +260,30 @@ class MainWindow_detect_Rpeak(QMainWindow):
# TODO获取检测方法的解耦
method_list = get_method()
if len(method_list) == 0 or method_list is None:
status = False
info = Constants.DETECT_RPEAK_LOAD_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Method_Not_Exist"]
result = Result().failure(info=Constants.DETECT_RPEAK_LOAD_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Method_Not_Exist"])
else:
status = True
info = Constants.DETECT_RPEAK_LOAD_FINISHED
if not status:
PublicFunc.text_output(self.ui, "(1/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = Result().success(info=Constants.DETECT_RPEAK_LOAD_FINISHED)
if not result.status:
PublicFunc.text_output(self.ui, "(1/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/2)" + result.info, Constants.TIPS_TYPE_INFO)
self.update_ui_comboBox_method(method_list)
# 导入数据
PublicFunc.progressbar_update(self, 2, 2, Constants.INPUTTING_DATA, 10)
status, info = self.data.open_file()
if not status:
PublicFunc.text_output(self.ui, "(2/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.open_file()
if not result.status:
PublicFunc.text_output(self.ui, "(2/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/2)" + result.info, Constants.TIPS_TYPE_INFO)
MainWindow_detect_Rpeak.__reset__()
self.__reset__()
PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_view__(self):
@ -292,25 +291,25 @@ class MainWindow_detect_Rpeak(QMainWindow):
# 数据预处理
PublicFunc.progressbar_update(self, 1, 3, Constants.DETECT_RPEAK_PROCESSING_DATA, 0)
status, info = self.data.preprocess()
if not status:
PublicFunc.text_output(self.ui, "(1/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.preprocess()
if not result.status:
PublicFunc.text_output(self.ui, "(1/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/3)" + result.info, Constants.TIPS_TYPE_INFO)
# 预测峰值
PublicFunc.progressbar_update(self, 2, 3, Constants.DETECT_RPEAK_PREDICTING_PEAK, 10)
status, info = self.data.predict_Rpeak()
if not status:
PublicFunc.text_output(self.ui, "(2/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.predict_Rpeak()
if not result.status:
PublicFunc.text_output(self.ui, "(2/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/3)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, Constants.DETECT_RPEAK_DATA_LENGTH_POINTS + str(len(self.data.raw_data)),
Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, Constants.DETECT_RPEAK_DURATION_MIN +
@ -321,14 +320,14 @@ class MainWindow_detect_Rpeak(QMainWindow):
# 绘图
PublicFunc.progressbar_update(self, 3, 3, Constants.DRAWING_DATA, 70)
status, info = self.__plot__()
if not status:
PublicFunc.text_output(self.ui, "(3/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.__plot__()
if not result.status:
PublicFunc.text_output(self.ui, "(3/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(3/3)" + result.info, Constants.TIPS_TYPE_INFO)
ButtonState["Current"]["pushButton_save"] = True
PublicFunc.finish_operation(self, ButtonState)
@ -350,20 +349,20 @@ class MainWindow_detect_Rpeak(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.peak.reshape(-1)).iloc[start:end]
status, info = self.data.save(chunk)
result = self.data.save(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(1/1)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, info, Constants.TIPS_TYPE_INFO)
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 reset_axes(self):
@ -391,20 +390,20 @@ class Data:
def open_file(self):
if not Path(Config["Path"]["Input"]).exists():
return False, Constants.INPUT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Data_Path_Not_Exist"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Data_Path_Not_Exist"])
try:
self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception:
return False, Constants.INPUT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Read_Data_Exception"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Read_Data_Exception"])
return True, Constants.INPUT_FINISHED
return Result().success(info=Constants.INPUT_FINISHED)
def preprocess(self):
if self.raw_data is None:
return False, Constants.DETECT_RPEAK_PROCESS_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Raw_Data_Not_Exist"]
return Result().failure(info=Constants.DETECT_RPEAK_PROCESS_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Raw_Data_Not_Exist"])
try:
self.processed_data = preprocess(self.raw_data,
@ -412,13 +411,13 @@ class Data:
Config["Filter"]["BandPassLow"],
Config["Filter"]["BandPassHigh"])
except Exception:
return False, Constants.DETECT_RPEAK_PROCESS_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Filter_Exception"]
return Result().failure(info=Constants.DETECT_RPEAK_PROCESS_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Filter_Exception"])
return True, Constants.DETECT_RPEAK_PROCESS_FINISHED
return Result().success(info=Constants.DETECT_RPEAK_PROCESS_FINISHED)
def predict_Rpeak(self):
if self.processed_data is None:
return False, Constants.DETECT_RPEAK_PREDICT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Processed_Data_Not_Exist"]
return Result().failure(info=Constants.DETECT_RPEAK_PREDICT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Processed_Data_Not_Exist"])
try:
self.peak, self.interval, self.RRIV = Rpeak_Detection(self.processed_data,
@ -426,17 +425,18 @@ class Data:
Config["PeaksValue"],
Config["DetectMethod"])
except Exception:
return False, Constants.DETECT_RPEAK_PREDICT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Predict_Exception"]
return Result().failure(info=Constants.DETECT_RPEAK_PREDICT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Predict_Exception"])
return True, Constants.DETECT_RPEAK_PREDICT_FINISHED
return Result().success(info=Constants.DETECT_RPEAK_PREDICT_FINISHED)
def save(self, chunk):
if self.peak is None:
return False, Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Peak_Not_Exist"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Peak_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False)
except Exception:
return False, Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Save_Exception"])
return True, Constants.SAVING_FINISHED
return Result().success(info=Constants.SAVING_FINISHED)

View File

@ -17,6 +17,7 @@ from yaml import dump, load, FullLoader
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.Filters.Preprocessing import data_preprocess_for_label_check
from func.utils.Result import Result
from ui.MainWindow.MainWindow_label_check import Ui_MainWindow_label_check
from ui.setting.label_check_input_setting import Ui_MainWindow_label_check_input_setting
@ -300,29 +301,33 @@ class MainWindow_label_check(QMainWindow):
@overrides
def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState)
reply = QMessageBox.question(self, '确认', '确认退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
QApplication.processEvents()
PublicFunc.__disableAllButton__(self, ButtonState)
# 清空画框
del self.point_peak_original
del self.point_peak_corrected
del self.annotation_tableWidget
self.ax0.clear()
self.ax1.clear()
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
QApplication.processEvents()
# 释放资源
del self.data
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
# 清空画框
del self.point_peak_original
del self.point_peak_corrected
del self.annotation_tableWidget
self.ax0.clear()
self.ax1.clear()
@staticmethod
def __reset__():
# 释放资源
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):
@ -351,16 +356,15 @@ class MainWindow_label_check(QMainWindow):
color=Constants.PLOT_COLOR_BLUE)
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
self.ax1.legend(loc=Constants.PLOT_UPPER_RIGHT)
status = True
info = Constants.DRAWING_FINISHED
self.canvas.draw()
self.ax0.autoscale(False)
self.ax1.autoscale(False)
return Result().success(info=Constants.DRAWING_FINISHED)
else:
status = False
info = Constants.DRAWING_FAILURE
self.canvas.draw()
self.ax0.autoscale(False)
self.ax1.autoscale(False)
return status, info
self.canvas.draw()
self.ax0.autoscale(False)
self.ax1.autoscale(False)
return Result().failure(info=Constants.DRAWING_FAILURE)
def __plot_peaks__(self):
try:
@ -372,10 +376,10 @@ class MainWindow_label_check(QMainWindow):
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
self.ax1.legend(loc=Constants.PLOT_UPPER_RIGHT)
except Exception:
return False, Constants.DRAWING_FAILURE
return Result().failure(info=Constants.DRAWING_FAILURE)
self.canvas.draw()
return True, Constants.DRAWING_FINISHED
return Result().success(info=Constants.DRAWING_FINISHED)
def __redraw_peaks__(self):
self.point_peak_corrected.remove()
@ -398,12 +402,9 @@ class MainWindow_label_check(QMainWindow):
for row, value in enumerate(self.data.corrected_peak):
item = QTableWidgetItem(str(value).strip())
self.ui.tableWidget_peak_corrected.setItem(row, 0, item)
status = True
info = Constants.UPDATING_FINISHED
return Result().success(info=Constants.UPDATING_FINISHED)
except Exception:
status = False
info = Constants.UPDATING_FAILURE
return status, info
return Result().failure(info=Constants.UPDATING_FAILURE)
def __update_config__(self):
Config["FindPeaks"]["MinInterval"] = self.ui.doubleSpinBox_findpeaks_min_interval.value()
@ -433,71 +434,71 @@ class MainWindow_label_check(QMainWindow):
# 导入数据
PublicFunc.progressbar_update(self, 1, 6, Constants.INPUTTING_DATA, 0)
status, info = self.data.open_file()
if not status:
PublicFunc.text_output(self.ui, "(1/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 获取存档
PublicFunc.progressbar_update(self, 2, 6, Constants.LABEL_CHECK_LOADING_ARCHIVE, 20)
status, info = self.data.get_archive()
if not status:
PublicFunc.text_output(self.ui, "(2/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.get_archive()
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 数据预处理
PublicFunc.progressbar_update(self, 3, 6, Constants.LABEL_CHECK_PROCESSING_DATA, 30)
status, info = self.data.preprocess()
if not status:
PublicFunc.text_output(self.ui, "(3/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.preprocess()
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(3/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 更新表格
PublicFunc.progressbar_update(self, 4, 6, Constants.UPDATING_TABLEWIDGET_AND_INFO, 50)
status, info = self.__update_tableWidget_and_info__()
if not status:
PublicFunc.text_output(self.ui, "(4/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.__update_tableWidget_and_info__()
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(4/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 绘图
PublicFunc.progressbar_update(self, 5, 6, Constants.DRAWING_DATA, 60)
status, info = self.__plot__()
if not status:
PublicFunc.text_output(self.ui, "(5/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.__plot__()
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(5/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 绘点
PublicFunc.progressbar_update(self, 6, 6, Constants.DRAWING_DATA, 80)
status, info = self.__plot_peaks__()
if not status:
PublicFunc.text_output(self.ui, "(6/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.__plot_peaks__()
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(6/6)" + result.info, Constants.TIPS_TYPE_INFO)
MainWindow_label_check.__reset__()
self.__reset__()
self.canvas.mpl_connect("motion_notify_event", self.on_motion)
self.figToolbar.action_Label_Multiple.setEnabled(True)
for action in self.figToolbar._actions.values():
@ -527,20 +528,20 @@ class MainWindow_label_check(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.corrected_peak.reshape(-1)).iloc[start:end]
status, info = self.data.save(chunk)
result = self.data.save(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(1/1)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, info, Constants.TIPS_TYPE_INFO)
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_move__(self):
@ -875,7 +876,7 @@ class Data:
def open_file(self):
if (not Path(Config["Path"]["Input_Signal"]).exists()) or (not Path(Config["Path"]["Input_Peak"]).exists()):
return False, Constants.INPUT_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Data_Path_Not_Exist"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Data_Path_Not_Exist"])
try:
self.raw_data = read_csv(Config["Path"]["Input_Signal"],
@ -885,23 +886,23 @@ class Data:
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception:
return False, Constants.INPUT_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Read_Data_Exception"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Read_Data_Exception"])
return True, Constants.INPUT_FINISHED
return Result().success(info=Constants.INPUT_FINISHED)
def get_archive(self):
if not Path(Config["Path"]["Save"]).exists():
self.corrected_peak = self.original_peak
return True, Constants.LABEL_CHECK_ARCHIVE_NOT_EXIST
return Result().success(info=Constants.LABEL_CHECK_ARCHIVE_NOT_EXIST)
else:
self.corrected_peak = read_csv(Config["Path"]["Save"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
return True, Constants.LABEL_CHECK_ARCHIVE_EXIST
return Result().success(info=Constants.LABEL_CHECK_ARCHIVE_EXIST)
def preprocess(self):
if self.raw_data is None:
return False, Constants.LABEL_CHECK_PROCESS_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Raw_Data_Not_Exist"]
return Result().failure(info=Constants.LABEL_CHECK_PROCESS_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Raw_Data_Not_Exist"])
try:
if Config["Mode"] == "BCG":
@ -921,20 +922,20 @@ class Data:
self.original_peak_y = [self.processed_data[x] for x in self.original_peak]
self.corrected_peak_y = [self.processed_data[x] for x in self.corrected_peak]
except Exception:
return False, Constants.LABEL_CHECK_PROCESS_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Filter_Exception"]
return Result().failure(info=Constants.LABEL_CHECK_PROCESS_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Filter_Exception"])
return True, Constants.LABEL_CHECK_PROCESS_FINISHED
return Result().success(info=Constants.LABEL_CHECK_PROCESS_FINISHED)
def save(self, chunk):
if self.corrected_peak is None:
return False, Constants.SAVING_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Peak_Not_Exist"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Peak_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False)
except Exception:
return False, Constants.SAVING_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Save_Exception"])
return True, Constants.SAVING_FINISHED
return Result().success(info=Constants.SAVING_FINISHED)
class CustomNavigationToolbar(NavigationToolbar2QT):

View File

@ -7,6 +7,7 @@ from yaml import dump, load, FullLoader
from func.utils.PublicFunc import PublicFunc
from ui.MainWindow.MainWindow_menu import Ui_Signal_Label
from func.Module_approximately_align import MainWindow_approximately_align
from func.Module_preprocess import MainWindow_preprocess
from func.Module_detect_Jpeak import MainWindow_detect_Jpeak
from func.Module_detect_Rpeak import MainWindow_detect_Rpeak
@ -40,6 +41,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.ui.plainTextEdit_root_path.setPlainText(Config["Path"]["Root"])
self.seek_sampID(Path(Config["Path"]["Root"]) / Path(ConfigParams.PUBLIC_PATH_ORGBCG_TEXT))
self.approximately_align = None
self.preprocess = None
self.detect_Jpeak = None
self.detect_Rpeak = None
@ -49,6 +51,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
# 绑定槽函数
self.ui.pushButton_open.clicked.connect(self.__slot_btn_open__)
self.ui.pushButton_approximately_align.clicked.connect(self.__slot_btn_approximately_align__)
self.ui.pushButton_preprocess_BCG.clicked.connect(self.__slot_btn_preprocess__)
self.ui.pushButton_preprocess_ECG.clicked.connect(self.__slot_btn_preprocess__)
self.ui.pushButton_detect_Jpeak.clicked.connect(self.__slot_btn_detect_Jpeak__)
@ -87,6 +90,12 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
else:
PublicFunc.msgbox_output(self, Constants.OPERATION_CANCELED, Constants.MSGBOX_TYPE_INFO)
def __slot_btn_approximately_align__(self):
self.approximately_align = MainWindow_approximately_align()
root_path = self.ui.plainTextEdit_root_path.toPlainText()
sampID = int(self.ui.comboBox_sampID.currentText())
self.approximately_align.show(root_path, sampID)
def __slot_btn_preprocess__(self):
self.preprocess = MainWindow_preprocess()

View File

@ -18,6 +18,7 @@ from yaml import dump, load, FullLoader
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Result import Result
from ui.MainWindow.MainWindow_precisely_align import Ui_MainWindow_precisely_align
from ui.setting.precisely_align_input_setting import Ui_MainWindow_precisely_align_input_setting
@ -401,46 +402,49 @@ class MainWindow_precisely_align(QMainWindow):
@overrides
def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState)
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()
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
QApplication.processEvents()
# 清空画框
del self.point0
del self.point1
del self.selected_point0
del self.selected_point1
del self.selected_point2
del self.selected_point3
del self.stem_black0
del self.stem_black1
del self.figToolbar.ax0_BCG_rectangle_front
del self.figToolbar.ax0_BCG_rectangle_back
del self.figToolbar.ax1_ECG_rectangle_front
del self.figToolbar.ax1_ECG_rectangle_back
if self.ax0 is not None:
self.ax0.clear()
if self.ax1 is not None:
self.ax1.clear()
if self.ax2 is not None:
self.ax2.clear()
if self.ax3 is not None:
self.ax3.clear()
if self.ax4 is not None:
self.ax4.clear()
# 清空画框
del self.point0
del self.point1
del self.selected_point0
del self.selected_point1
del self.selected_point2
del self.selected_point3
del self.stem_black0
del self.stem_black1
del self.figToolbar.ax0_BCG_rectangle_front
del self.figToolbar.ax0_BCG_rectangle_back
del self.figToolbar.ax1_ECG_rectangle_front
del self.figToolbar.ax1_ECG_rectangle_back
if self.ax0 is not None:
self.ax0.clear()
if self.ax1 is not None:
self.ax1.clear()
if self.ax2 is not None:
self.ax2.clear()
if self.ax3 is not None:
self.ax3.clear()
if self.ax4 is not None:
self.ax4.clear()
# 释放资源
del self.data
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
# 释放资源
del self.data
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
else:
event.ignore()
@staticmethod
def __reset__():
def __reset__(self):
ButtonState["Current"].update(ButtonState["Default"].copy())
def __plot__(self, plot_element=None):
@ -483,8 +487,8 @@ class MainWindow_precisely_align(QMainWindow):
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
self.ax1.legend(loc=Constants.PLOT_UPPER_RIGHT)
status = True
info = Constants.DRAWING_FINISHED
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
elif sender == self.ui.pushButton_calculate_correlation and plot_element is not None and plot_element["mode"] == "init":
self.gs = gridspec.GridSpec(2, 2, height_ratios=[1, 1], width_ratios=[1, 1])
self.fig.subplots_adjust(top=0.88, bottom=0.05, right=0.98, left=0.05, hspace=0.15, wspace=0.15)
@ -549,8 +553,8 @@ class MainWindow_precisely_align(QMainWindow):
self.ax2.legend(loc=Constants.PLOT_UPPER_RIGHT)
self.ax3.legend(loc=Constants.PLOT_UPPER_RIGHT)
status = True
info = Constants.DRAWING_FINISHED
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
elif sender == self.ui.pushButton_correlation_align or (plot_element is not None and plot_element["mode"] == "select"):
self.gs = gridspec.GridSpec(1, 1, height_ratios=[1])
self.fig.subplots_adjust(top=0.95, bottom=0.05, right=0.98, left=0.05, hspace=0, wspace=0)
@ -570,8 +574,8 @@ class MainWindow_precisely_align(QMainWindow):
self.ax4.legend(loc=Constants.PLOT_UPPER_RIGHT)
status = True
info = Constants.DRAWING_FINISHED
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
elif sender == self.ui.pushButton_view_align:
self.gs = gridspec.GridSpec(1, 1, height_ratios=[1])
self.fig.subplots_adjust(top=0.95, bottom=0.05, right=0.98, left=0.05, hspace=0, wspace=0)
@ -587,14 +591,11 @@ class MainWindow_precisely_align(QMainWindow):
self.ax4.legend(loc=Constants.PLOT_UPPER_RIGHT)
status = True
info = Constants.DRAWING_FINISHED
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
else:
status = False
info = Constants.DRAWING_FAILURE
self.canvas.draw()
return status, info
self.canvas.draw()
return Result().failure(info=Constants.DRAWING_FAILURE)
def __update_info__(self):
self.ui.spinBox_BCG_front_JJIV_1.setValue(Config["IV_Coordinate"]["BCG_front_1"])
@ -625,38 +626,38 @@ class MainWindow_precisely_align(QMainWindow):
# 导入数据
PublicFunc.progressbar_update(self, 1, 3, Constants.INPUTTING_DATA, 0)
status, info = self.data.open_file()
if not status:
PublicFunc.text_output(self.ui, "(1/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.open_file()
if not result.status:
PublicFunc.text_output(self.ui, "(1/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/3)" + result.info, Constants.TIPS_TYPE_INFO)
# 处理数据
PublicFunc.progressbar_update(self, 2, 3, Constants.DRAWING_DATA, 50)
status, info, result = self.data.data_process_for_calculate_correlation()
if not status:
PublicFunc.text_output(self.ui, "(2/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.data_process_for_calculate_correlation()
if not result.status:
PublicFunc.text_output(self.ui, "(2/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/3)" + result.info, Constants.TIPS_TYPE_INFO)
# 绘图
PublicFunc.progressbar_update(self, 3, 3, Constants.DRAWING_DATA, 70)
status, info = self.__plot__(result)
if not status:
PublicFunc.text_output(self.ui, "(3/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.__plot__(result.data)
if not result.status:
PublicFunc.text_output(self.ui, "(3/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(3/3)" + result.info, Constants.TIPS_TYPE_INFO)
MainWindow_precisely_align.__reset__()
self.__reset__()
self.figToolbar.action_Get_Range.setEnabled(True)
self.rect_down = min(self.ax0.get_ylim()[0], self.ax1.get_ylim()[0]) - 10000
self.rect_up = max(self.ax0.get_ylim()[1], self.ax1.get_ylim()[1]) + 10000
@ -681,45 +682,45 @@ class MainWindow_precisely_align(QMainWindow):
# 计算前段相关性
PublicFunc.progressbar_update(self, 1, 3, Constants.PRECISELY_ALIGN_CALCULATING_CORRELATION_FRONT, 0)
status, info, result1 = self.data.calculate_correlation_front(mode, shift_front)
if not status:
PublicFunc.text_output(self.ui, "(1/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result1 = self.data.calculate_correlation_front(mode, shift_front)
if not result1.status:
PublicFunc.text_output(self.ui, "(1/3)" + result1.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result1.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(1/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/3)" + result1.info, Constants.TIPS_TYPE_INFO)
# 计算后段相关性
PublicFunc.progressbar_update(self, 2, 3, Constants.PRECISELY_ALIGN_CALCULATING_CORRELATION_BACK, 30)
status, info, result2 = self.data.calculate_correlation_back(mode, shift_back)
if not status:
PublicFunc.text_output(self.ui, "(2/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result2 = self.data.calculate_correlation_back(mode, shift_back)
if not result2.status:
PublicFunc.text_output(self.ui, "(2/3)" + result2.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result2.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(2/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/3)" + result2.info, Constants.TIPS_TYPE_INFO)
# 绘图
PublicFunc.progressbar_update(self, 3, 3, Constants.DRAWING_DATA, 60)
result = {}
result.update(result1)
result.update(result2)
result.update(result1.data)
result.update(result2.data)
result.update({"mode": mode})
if mode == "init":
status, info = self.__plot__(result)
result = self.__plot__(result)
elif mode == "select":
status, info = self.redraw_calculate_coordination(result)
result = self.redraw_calculate_coordination(result)
else:
raise ValueError("模式不存在")
if not status:
PublicFunc.text_output(self.ui, "(3/3)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
if not result.status:
PublicFunc.text_output(self.ui, "(3/3)" + 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/3)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(3/3)" + result.info, Constants.TIPS_TYPE_INFO)
self.figToolbar.action_Get_Range.setEnabled(False)
self.figToolbar.deactivate_figToorbar_getRange_mode()
@ -739,31 +740,31 @@ class MainWindow_precisely_align(QMainWindow):
# 处理相关对齐
PublicFunc.progressbar_update(self, 1, 2, Constants.PRECISELY_ALIGN_ALIGNING_CORRELATION, 0)
status, info, result = self.data.correlation_align(mode)
if not status:
PublicFunc.text_output(self.ui, "(1/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.correlation_align(mode)
if not result.status:
PublicFunc.text_output(self.ui, "(1/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/2)" + result.info, Constants.TIPS_TYPE_INFO)
# 绘图
PublicFunc.progressbar_update(self, 2, 2, Constants.DRAWING_DATA, 50)
result.update({"mode": mode})
result.data.update({"mode": mode})
if mode == "init":
status, info = self.__plot__(result)
result = self.__plot__(result.data)
elif mode == "select":
status, info = self.redraw_correlation_align(result)
result = self.redraw_correlation_align(result.data)
else:
raise ValueError("模式不存在")
if not status:
PublicFunc.text_output(self.ui, "(2/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
if not result.status:
PublicFunc.text_output(self.ui, "(2/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/2)" + result.info, Constants.TIPS_TYPE_INFO)
ButtonState["Current"].update(ButtonState["Statue_3"].copy())
PublicFunc.finish_operation(self, ButtonState)
@ -773,25 +774,25 @@ class MainWindow_precisely_align(QMainWindow):
# 数据后处理
PublicFunc.progressbar_update(self, 1, 2, Constants.PRECISELY_ALIGN_POSTPROCESSING_VIEW, 0)
status, info = self.data.data_postprocess()
if not status:
PublicFunc.text_output(self.ui, "(1/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.data_postprocess()
if not result.status:
PublicFunc.text_output(self.ui, "(1/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/2)" + result.info, Constants.TIPS_TYPE_INFO)
# 绘图
PublicFunc.progressbar_update(self, 2, 2, Constants.DRAWING_DATA, 50)
status, info = self.__plot__()
if not status:
PublicFunc.text_output(self.ui, "(2/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.__plot__()
if not result.status:
PublicFunc.text_output(self.ui, "(2/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/2)" + result.info, Constants.TIPS_TYPE_INFO)
ButtonState["Current"].update(ButtonState["Statue_4"].copy())
PublicFunc.finish_operation(self, ButtonState)
@ -805,14 +806,14 @@ class MainWindow_precisely_align(QMainWindow):
# 保存对齐信息
PublicFunc.progressbar_update(self, 1, 6, Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO, 0)
status, info = self.data.save_alignInfo()
if not status:
PublicFunc.text_output(self.ui, "(1/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.save_alignInfo()
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 保存切割后orgBcg
PublicFunc.progressbar_update(self, 2, 6, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG, 0)
@ -823,18 +824,18 @@ class MainWindow_precisely_align(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.res_orgBcg.reshape(-1)).iloc[start:end]
status, info = self.data.save_res_orgBcg(chunk)
result = self.data.save_res_orgBcg(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(2/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 保存切割后BCG
PublicFunc.progressbar_update(self, 3, 6, Constants.PRECISELY_ALIGN_SAVING_RES_BCG, 0)
@ -845,18 +846,18 @@ class MainWindow_precisely_align(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.res_BCG.reshape(-1)).iloc[start:end]
status, info = self.data.save_res_BCG(chunk)
result = self.data.save_res_BCG(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(3/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(3/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 保存切割后ECG
PublicFunc.progressbar_update(self, 4, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG, 0)
@ -867,18 +868,18 @@ class MainWindow_precisely_align(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.cut_ECG.reshape(-1)).iloc[start:end]
status, info = self.data.save_cut_ECG(chunk)
result = self.data.save_cut_ECG(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(4/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(4/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 保存切割后J峰
PublicFunc.progressbar_update(self, 5, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK, 0)
@ -889,18 +890,18 @@ class MainWindow_precisely_align(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.cut_Jpeak.reshape(-1)).iloc[start:end]
status, info = self.data.save_Jpeak(chunk)
result = self.data.save_Jpeak(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(5/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(5/6)" + result.info, Constants.TIPS_TYPE_INFO)
# 保存切割后R峰
PublicFunc.progressbar_update(self, 6, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK, 0)
@ -911,20 +912,20 @@ class MainWindow_precisely_align(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.cut_Rpeak.reshape(-1)).iloc[start:end]
status, info = self.data.save_Rpeak(chunk)
result = self.data.save_Rpeak(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(6/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, Constants.SAVING_FINISHED, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(6/6)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
def __update_coordinate__(self):
@ -1065,10 +1066,9 @@ class MainWindow_precisely_align(QMainWindow):
self.ax2.set_ylim(self.ax2_ylime)
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
return True, Constants.DRAWING_FINISHED
return False, Constants.DRAWING_FAILURE
return Result().failure(info=Constants.DRAWING_FAILURE)
def redraw_correlation_align(self, plot_element=None):
if plot_element is not None and plot_element["mode"] == "select":
@ -1103,10 +1103,9 @@ class MainWindow_precisely_align(QMainWindow):
self.ax4.set_ylim(self.ax4_ylime)
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
return True, Constants.DRAWING_FINISHED
return False, Constants.DRAWING_FAILURE
return Result().failure(info=Constants.DRAWING_FAILURE)
def toggle_home(self):
if self.ax0 is not None:
@ -1424,7 +1423,7 @@ class Data:
or (not Path(Config["Path"]["Input_Jpeak"]).exists())
or (not Path(Config["Path"]["Input_ECG"]).exists())
or (not Path(Config["Path"]["Input_Rpeak"]).exists())):
return False, Constants.INPUT_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Path_Not_Exist"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Path_Not_Exist"])
try:
self.raw_orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
@ -1445,15 +1444,13 @@ class Data:
self.argmax_BCG = np_argmax(self.raw_BCG)
self.argmax_ECG = np_argmax(self.raw_ECG)
except Exception:
return False, Constants.INPUT_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Read_Data_Exception"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Read_Data_Exception"])
return True, Constants.INPUT_FINISHED
return Result().success(info=Constants.INPUT_FINISHED)
def data_process_for_calculate_correlation(self):
result = {}
if self.Jpeak is None or self.Rpeak is None:
return False, Constants.PRECISELY_ALIGN_PROCESS_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Not_Exist"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_PROCESS_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Not_Exist"])
try:
self.JJIs = diff(self.Jpeak)
@ -1463,20 +1460,18 @@ class Data:
result = {"JJIVs": JJIVs, "RRIVs": RRIVs}
except Exception:
return False, Constants.PRECISELY_ALIGN_PROCESS_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Process_Data_Exception"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_PROCESS_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Process_Data_Exception"])
return True, Constants.PRECISELY_ALIGN_PROCESS_FINISHED, result
return Result().success(info=Constants.PRECISELY_ALIGN_PROCESS_FINISHED, data=result)
def calculate_correlation_front(self, mode, shift_front=None):
result = {}
if ((Config["IV_Coordinate"]["BCG_front_1"] == Config["IV_Coordinate"]["BCG_front_2"])
or (Config["IV_Coordinate"]["ECG_front_1"] == Config["IV_Coordinate"]["ECG_front_2"])):
return False, Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_FRONT + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_Value_Equal"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_FRONT + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_Value_Equal"])
if ((Config["IV_Coordinate"]["BCG_front_2"] - Config["IV_Coordinate"]["BCG_front_1"])
>= (Config["IV_Coordinate"]["ECG_front_2"] - Config["IV_Coordinate"]["ECG_front_1"])):
return False, Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_FRONT + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_JJIVRange_too_Large"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_FRONT + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_JJIVRange_too_Large"])
try:
if mode == "init":
@ -1530,20 +1525,18 @@ class Data:
}
}
except Exception:
return False, Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_FRONT + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_Exception"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_FRONT + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_Exception"])
return True, Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_FRONT, result
return Result().success(info=Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_FRONT, data=result)
def calculate_correlation_back(self, mode, shift_back=None):
result = {}
if ((Config["IV_Coordinate"]["BCG_back_1"] == Config["IV_Coordinate"]["BCG_back_2"])
or (Config["IV_Coordinate"]["ECG_back_1"] == Config["IV_Coordinate"]["ECG_back_2"])):
return False, Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_BACK + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_Value_Equal"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_BACK + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_Value_Equal"])
if ((Config["IV_Coordinate"]["BCG_back_2"] - Config["IV_Coordinate"]["BCG_back_1"])
>= (Config["IV_Coordinate"]["ECG_back_2"] - Config["IV_Coordinate"]["ECG_back_1"])):
return False, Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_BACK + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_JJIVRange_too_Large"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_BACK + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_JJIVRange_too_Large"])
try:
if mode == "init":
@ -1597,13 +1590,11 @@ class Data:
}
}
except Exception:
return False, Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_BACK + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_Exception"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_BACK + Constants.PRECISELY_ALIGN_FAILURE_REASON["Calculate_Correlation_Exception"])
return True, Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_BACK, result
return Result().success(info=Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_BACK, data=result)
def correlation_align(self, mode):
result = {}
try:
if mode == "init":
anchor0 = [Config["front"]["anchor_R"], Config["front"]["anchor_J"]]
@ -1683,9 +1674,9 @@ class Data:
else:
raise ValueError("模式不存在")
except Exception:
return False, Constants.PRECISELY_ALIGN_ALIGN_CORRELATION_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Correlation_Align_Exception"], result
return Result().failure(info=Constants.PRECISELY_ALIGN_ALIGN_CORRELATION_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Correlation_Align_Exception"])
return True, Constants.PRECISELY_ALIGN_ALIGN_CORRELATION_FINISHED, result
return Result().success(info=Constants.PRECISELY_ALIGN_ALIGN_CORRELATION_FINISHED, data=result)
def data_postprocess(self):
try:
@ -1738,9 +1729,10 @@ class Data:
Config["frontcut_index_ECG"] = frontcut_index_ECG
Config["backcut_index_ECG"] = backcut_index_ECG
except Exception:
return False, Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["PostProcess_Align_Exception"]
return Result().failure(info=Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["PostProcess_Align_Exception"])
return True, f"{Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FINISHED}BCG前后段被切割的坐标值为[{frontcut_index_BCG}, {backcut_index_BCG}]ECG前后段被切割的坐标值为[{frontcut_index_ECG}, {backcut_index_ECG}]"
info = f"{Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FINISHED}BCG前后段被切割的坐标值为[{frontcut_index_BCG}, {backcut_index_BCG}]ECG前后段被切割的坐标值为[{frontcut_index_ECG}, {backcut_index_ECG}]"
return Result().success(info=info)
def save_alignInfo(self):
try:
@ -1778,64 +1770,64 @@ class Data:
DataFrame(save_data).to_csv(Config["Path"]["Save_BCG_AlignInfo"], index=False, header=False)
DataFrame(save_data).to_csv(Config["Path"]["Save_ECG_AlignInfo"], index=False, header=False)
except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"])
return True, Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FINISHED
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FINISHED)
def save_res_orgBcg(self, chunk):
if self.res_orgBcg is None:
return False, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["res_orgBcg_Not_Exist"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["res_orgBcg_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save_orgBcg"], mode='a', index=False, header=False)
except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"])
return True, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FINISHED
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FINISHED)
def save_res_BCG(self, chunk):
if self.res_BCG is None:
return False, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["res_BCG_Not_Exist"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["res_BCG_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save_BCG"], mode='a', index=False, header=False)
except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"])
return True, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FINISHED
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FINISHED)
def save_cut_ECG(self, chunk):
if self.cut_ECG is None:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_ECG_Not_Exist"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_ECG_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save_ECG"], mode='a', index=False, header=False)
except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"])
return True, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FINISHED
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FINISHED)
def save_Jpeak(self, chunk):
if self.cut_Jpeak is None:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_Jpeak_Not_Exist"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_Jpeak_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save_Jpeak"], mode='a', index=False, header=False)
except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"])
return True, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FINISHED
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FINISHED)
def save_Rpeak(self, chunk):
if self.cut_Rpeak is None:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_Rpeak_Not_Exist"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_Rpeak_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save_Rpeak"], mode='a', index=False, header=False)
except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"])
return True, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FINISHED
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FINISHED)
class CustomNavigationToolbar(NavigationToolbar2QT):

View File

@ -14,6 +14,7 @@ from yaml import dump, load, FullLoader
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.Filters.Preprocessing import Butterworth_for_BCG_PreProcess, Butterworth_for_ECG_PreProcess
from func.utils.Result import Result
from ui.MainWindow.MainWindow_preprocess import Ui_MainWindow_preprocess
from ui.setting.preprocess_input_setting import Ui_MainWindow_preprocess_input_setting
@ -237,25 +238,28 @@ class MainWindow_preprocess(QMainWindow):
@overrides
def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState)
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()
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
QApplication.processEvents()
# 清空画框
self.ax0.clear()
# 清空画框
self.ax0.clear()
# 释放资源
del self.data
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
# 释放资源
del self.data
self.fig.clf()
plt.close(self.fig)
self.deleteLater()
collect()
self.canvas = None
event.accept()
else:
event.ignore()
@staticmethod
def __reset__():
def __reset__(self):
ButtonState["Current"].update(ButtonState["Default"].copy())
ButtonState["Current"]["pushButton_view"] = True
@ -273,14 +277,11 @@ class MainWindow_preprocess(QMainWindow):
color=Constants.PLOT_COLOR_BLUE,
label=Constants.PREPROCESS_PLOT_LABEL_PROCESSED_DATA)
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
status = True
info = Constants.DRAWING_FINISHED
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FINISHED)
else:
status = False
info = Constants.DRAWING_FAILURE
self.canvas.draw()
return status, info
self.canvas.draw()
return Result().success(info=Constants.DRAWING_FAILURE)
def __update_config__(self):
if self.mode == "BCG":
@ -306,16 +307,16 @@ class MainWindow_preprocess(QMainWindow):
# 导入数据
PublicFunc.progressbar_update(self, 1, 1, Constants.INPUTTING_DATA, 0)
status, info = self.data.open_file()
if not status:
PublicFunc.text_output(self.ui, "(1/1)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.open_file()
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_INFO)
MainWindow_preprocess.__reset__()
self.__reset__()
PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_view__(self):
@ -323,25 +324,25 @@ class MainWindow_preprocess(QMainWindow):
# 数据预处理
PublicFunc.progressbar_update(self, 1, 2, Constants.PREPROCESS_PROCESSING_DATA, 0)
status, info = self.data.preprocess()
if not status:
PublicFunc.text_output(self.ui, "(1/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.data.preprocess()
if not result.status:
PublicFunc.text_output(self.ui, "(1/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(1/2)" + result.info, Constants.TIPS_TYPE_INFO)
# 绘图
PublicFunc.progressbar_update(self, 2, 2, Constants.DRAWING_DATA, 50)
status, info = self.__plot__()
if not status:
PublicFunc.text_output(self.ui, "(2/2)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
result = self.__plot__()
if not result.status:
PublicFunc.text_output(self.ui, "(2/2)" + 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/2)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.text_output(self.ui, "(2/2)" + result.info, Constants.TIPS_TYPE_INFO)
ButtonState["Current"]["pushButton_save"] = True
PublicFunc.finish_operation(self, ButtonState)
@ -363,20 +364,20 @@ class MainWindow_preprocess(QMainWindow):
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.processed_data.reshape(-1)).iloc[start:end]
status, info = self.data.save(chunk)
result = self.data.save(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not status:
PublicFunc.text_output(self.ui, "(1/1)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
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)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, info, Constants.TIPS_TYPE_INFO)
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 reset_axes(self):
@ -393,20 +394,20 @@ class Data:
def open_file(self):
if not Path(Config["Path"]["Input"]).exists():
return False, Constants.INPUT_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Data_Path_Not_Exist"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Data_Path_Not_Exist"])
try:
self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception:
return False, Constants.INPUT_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Read_Data_Exception"]
return Result().failure(info=Constants.INPUT_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Read_Data_Exception"])
return True, Constants.INPUT_FINISHED
return Result().success(info=Constants.INPUT_FINISHED)
def preprocess(self):
if self.raw_data is None:
return False, Constants.PREPROCESS_PROCESS_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Raw_Data_Not_Exist"]
Result().failure(info=Constants.PREPROCESS_PROCESS_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Raw_Data_Not_Exist"])
try:
if Config["InputConfig"]["Freq"] != Config["OutputConfig"]["Freq"]:
@ -428,17 +429,18 @@ class Data:
else:
raise ValueError("模式不存在")
except Exception:
return False, Constants.PREPROCESS_PROCESS_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Filter_Exception"]
Result().failure(info=Constants.PREPROCESS_PROCESS_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Filter_Exception"])
return Result().success(info=Constants.PREPROCESS_PROCESS_FINISHED)
return True, Constants.PREPROCESS_PROCESS_FINISHED
def save(self, chunk):
if self.processed_data is None:
return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Processed_Data_Not_Exist"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Processed_Data_Not_Exist"])
try:
chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False, float_format='%.4f')
except Exception:
return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Save_Exception"]
return Result().failure(info=Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Save_Exception"])
return True, Constants.SAVING_FINISHED
return Result().success(Constants.SAVING_FINISHED)

View File

@ -30,6 +30,24 @@ class ConfigParams:
FONT: str = "Microsoft YaHei UI"
# 数据粗同步
APPROXIMATELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_approximately_align.yaml"
APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
"InputConfig": {
"orgBcgFreq": 1000,
"ThoFreq": 100,
"AbdFreq": 100
},
"ApplyFrequency": 5,
"Filter": {
"BandPassOrder": 4,
"BandPassLow": 0.01,
"BandPassHigh": 0.7
}
}
APPROXIMATELY_ALIGN_INPUT_ORGBCG_FILENAME: str = "orgBcg_Raw_"
APPROXIMATELY_ALIGN_INPUT_THO_FILENAME: str = "Effort Tho_Raw_"
APPROXIMATELY_ALIGN_INPUT_ABD_FILENAME: str = "Effort Abd_Raw_"
APPROXIMATELY_ALIGN_SAVE_FILENAME: str = "Approximately_Align_Info"
# 预处理
PREPROCESS_CONFIG_FILE_PATH: str = "./config/Config_preprocess.yaml"
@ -200,21 +218,6 @@ class ConfigParams:
VALIDATOR_INTEGER = QIntValidator(-2**31, 2**31 - 1)
VALIDATOR_DOUBLE = QDoubleValidator(-1e100, 1e100, 10)
# 数据粗同步
APPROXIMATELY_ALIGN_INPUT_ORGBCG_FILENAME: str = "orgBcg_Raw_"
APPROXIMATELY_ALIGN_INPUT_PSG_FILENAME: str = "A"
APPROXIMATELY_ALIGN_SAVE_FILENAME: str = "Approximately_Align_Info"
APPROXIMATELY_ALIGN_INPUT_ORGBCG_DEFAULT_FS: int = 1000
APPROXIMATELY_ALIGN_INPUT_PSG_DEFAULT_FS: int = 100
APPROXIMATELY_ALIGN_THO_CUSTOM_CHANNEL_DEFAULT: int = 3
APPROXIMATELY_ALIGN_ABD_CUSTOM_CHANNE_DEFAULT: int = 4
APPROXIMATELY_ALIGN_BUTTERORDER_DEFAULT: int = 4
APPROXIMATELY_ALIGN_BUTTERLOWPASSFREQ_CHANNE_DEFAULT: float = 0.01
APPROXIMATELY_ALIGN_BUTTERHIGHPASSFREQ_DEFAULT: float = 0.70
APPROXIMATELY_ALIGN_APPLYFREQ_DEFAULT: float = 5
# 体动打标
ARTIFACT_LABEL_INPUT_BCG_FILENAME: str = "BCG_sync_"
ARTIFACT_LABEL_INPUT_XINXIAO_FILENAME: str = "orgBcg_sync_"

View File

@ -74,6 +74,65 @@ class Constants:
}
"""
# 数据粗同步
APPROXIMATELY_ONLY_ALIGN_RESAMPLING: str = "正在仅重采样"
APPROXIMATELY_ONLY_ALIGN_RESAMPLE_FINISHED: str = "仅重采样完成"
APPROXIMATELY_ONLY_ALIGN_RESAMPLE_FAILURE: str = "仅重采样失败"
APPROXIMATELY_RESP_GETTING: str = "正在呼吸提取"
APPROXIMATELY_RESP_GET_FINISHED: str = "呼吸提取完成"
APPROXIMATELY_RESP_GET_FAILURE: str = "呼吸提取失败"
APPROXIMATELY_PRE_ALIGN_RESAMPLING: str = "正在预重采样"
APPROXIMATELY_PRE_ALIGN_RESAMPLE_FINISHED: str = "预重采样完成"
APPROXIMATELY_PRE_ALIGN_RESAMPLE_FAILURE: str = "预重采样失败"
APPROXIMATELY_DELETING_BASE: str = "正在去基线"
APPROXIMATELY_DELETE_BASE_FINISHED: str = "去基线完成"
APPROXIMATELY_DELETE_BASE_FAILURE: str = "去基线失败"
APPROXIMATELY_STANDARDIZING: str = "正在标准化"
APPROXIMATELY_STANDARDIZE_FINISHED: str = "标准化完成"
APPROXIMATELY_STANDARDIZE_FAILURE: str = "标准化失败"
APPROXIMATELY_ALIGN_RESAMPLING: str = "正在重采样"
APPROXIMATELY_ALIGN_RESAMPLE_FINISHED: str = "重采样完成"
APPROXIMATELY_ALIGN_RESAMPLE_FAILURE: str = "重采样失败"
APPROXIMATELY_CORRELATION_CALCULATING1: str = "正在计算互相关1/2"
APPROXIMATELY_CORRELATION_CALCULATE1_FINISHED: str = "计算互相关1/2完成"
APPROXIMATELY_CORRELATION_CALCULATE1_FAILURE: str = "计算互相关1/2失败"
APPROXIMATELY_CORRELATION_CALCULATING2: str = "正在计算互相关2/2"
APPROXIMATELY_CORRELATION_CALCULATE2_FINISHED: str = "计算互相关2/2完成"
APPROXIMATELY_CORRELATION_CALCULATE2_FAILURE: str = "计算互相关2/2失败"
APPROXIMATELY_MAXVALUE_POS_CALCULATING: str = "正在计算最大值位置"
APPROXIMATELY_MAXVALUE_POS_CALCULATE_FINISHED: str = "计算最大值位置完成"
APPROXIMATELY_MAXVALUE_POS_CALCULATE_FAILURE: str = "计算最大值位置失败"
APPROXIMATELY_EPOCH_GETTING: str = "正在获取epoch"
APPROXIMATELY_EPOCH_GET_FINISHED: str = "获取epoch完成"
APPROXIMATELY_EPOCH_GET_FAILURE: str = "获取epoch失败"
APPROXIMATELY_ALIGN_FAILURE_REASON = {
"Data_Path_Not_Exist": "(路径不存在)",
"Read_Data_Exception": "(读取数据异常)",
"Raw_Data_Not_Exist": "(原始数据不存在)",
"Only_Resample_Exception": "(仅重采样异常)",
"Resp_Get_Exception": "(呼吸提取异常)",
"Pre_Resample_Exception": "(预重采样异常)",
"Delete_Base_Exception": "(去基线异常)",
"Standardize_Exception": "(标准化异常)",
"Resample_Exception": "(重采样异常)",
"Calculate_Correlation1_Exception": "计算互相关1/2异常",
"Calculate_Correlation2_Exception": "计算互相关2/2异常",
"Calculate_Maxvalue_Pos_Exception": "(计算最大值位置异常)",
"Get_Epoch_Exception": "获取epoch异常",
"Processed_Data_Not_Exist": "(处理后数据不存在)",
"Save_Exception": "(保存异常)"
}
# 预处理
PREPROCESS_PROCESSING_DATA: str = "正在处理数据"
PREPROCESS_PROCESS_FINISHED: str = "处理完成"
@ -263,8 +322,8 @@ class Constants:
PRECISELY_ALIGN_PLOT_LABEL_CORRE_RRIV_JJIV: str = "corre(RRIV, JJIV)"
PRECISELY_ALIGN_PLOT_LABEL_ECG: str = "ECG"
PRECISELY_ALIGN_PLOT_LABEL_BCG: str = "BCG"
PRECISELY_ALIGN_PLOT_LABEL_RPEAK: str = "Rpeak_ECG"
PRECISELY_ALIGN_PLOT_LABEL_JPEAK: str = "Jpeak_BCG"
PRECISELY_ALIGN_PLOT_LABEL_RPEAK: str = "peak_ECG"
PRECISELY_ALIGN_PLOT_LABEL_JPEAK: str = "peak_BCG"
PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT: str = "Selected Point"
PRECISELY_ALIGN_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无有效点"
PRECISELY_ALIGN_ACTION_GET_RANGE_NAME: str = f"设置范围({ConfigParams.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY})"
@ -298,13 +357,6 @@ class Constants:
# 体动标注
# TODO弃用
# 数据粗同步
APPROXIMATELY_ALIGN_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.APPROXIMATELY_ALIGN_INPUT_ORGBCG_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.APPROXIMATELY_ALIGN_INPUT_PSG_FILENAME}{ConfigParams.ENDSWITH_EDF},无法执行<数据粗同步>"
APPROXIMATELY_ALIGN_FILES_FOUND: str = f"找到{ConfigParams.APPROXIMATELY_ALIGN_INPUT_ORGBCG_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.APPROXIMATELY_ALIGN_INPUT_PSG_FILENAME}{ConfigParams.ENDSWITH_EDF}"
APPROXIMATELY_ALIGN_RUNNING: str = "开始执行任务<数据粗同步>"
APPROXIMATELY_RECORD_NOT_FOUND: str = "没有保存记录"
# 体动打标
ARTIFACT_LABEL_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.ARTIFACT_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.ARTIFACT_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<体动标注>"
ARTIFACT_LABEL_FILES_FOUND: str = f"找到{ConfigParams.ARTIFACT_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.ARTIFACT_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT}"

48
func/utils/Result.py Normal file
View File

@ -0,0 +1,48 @@
class Result:
def __init__(self, status=False, info="", data=None):
"""
初始化 Result 对象
:param status: 布尔值,表示业务操作是否成功,默认为 False
:param info: 字符串,表示业务提示信息,默认为空字符串
:param data: 字典,表示返回的数据,默认为 None
"""
self.status = status
self.info = info
self.data = data if data is not None else {}
def success(self, info="", data=None):
"""
设置业务操作成功
:param info: 成功提示信息
:param data: 返回的数据
"""
self.status = True
self.info = info
self.data = data if data is not None else {}
return self
def failure(self, info=""):
"""
设置业务操作失败
:param info: 失败提示信息
"""
self.status = False
self.info = info
return self
def to_dict(self):
"""
将对象转换为字典
:return: 包含 status、info 和 data 的字典
"""
return {
"status": self.status,
"info": self.info,
"data": self.data
}
def __str__(self):
"""
返回对象的字符串表示
"""
return str(self.to_dict())