1、完成了<数据精对齐>的所有代码,修复了部分内容

2、新增命名规范
This commit is contained in:
2025-05-08 19:53:01 +08:00
parent 6a250a64a0
commit baa2923e5b
11 changed files with 827 additions and 675 deletions

View File

@ -111,26 +111,48 @@ class SettingWindow(QMainWindow):
Config.update({
"Path": {
"Input_orgBcg": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_INPUT_ORGBCG_FILENAME +
str(Config["InputConfig"]["ECGFreq"]) +
ConfigParams.ENDSWITH_TXT))),
"Input_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_INPUT_BCG_FILENAME +
str(Config["InputConfig"]["ECGFreq"]) +
ConfigParams.ENDSWITH_TXT))),
"Input_Jpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_INPUT_JPEAK_FILENAME +
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_INPUT_BCG_FILENAME +
str(Config["InputConfig"]["ECGFreq"]) +
ConfigParams.ENDSWITH_TXT))),
"Input_Jpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_INPUT_JPEAK_FILENAME +
ConfigParams.ENDSWITH_TXT))),
"Input_ECG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_INPUT_ECG_FILENAME +
str(Config["InputConfig"]["ECGFreq"]) +
ConfigParams.ENDSWITH_TXT))),
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_INPUT_ECG_FILENAME +
str(Config["InputConfig"]["ECGFreq"]) +
ConfigParams.ENDSWITH_TXT))),
"Input_Rpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_INPUT_RPEAK_FILENAME +
ConfigParams.ENDSWITH_TXT))),
"Save_BCG_AlignInfo": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_SAVE_BCG_ALIGNINFO_FILENAME +
ConfigParams.ENDSWITH_TXT))),
"Save_ECG_AlignInfo": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_SAVE_ECG_ALIGNINFO_FILENAME +
ConfigParams.ENDSWITH_TXT))),
"Save_orgBcg": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_SAVE_ORGBCG_FILENAME +
str(Config["InputConfig"]["ECGFreq"]) +
ConfigParams.ENDSWITH_TXT))),
"Save_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_SAVE_BCG_FILENAME +
ConfigParams.ENDSWITH_TXT))),
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_SAVE_BCG_FILENAME +
str(Config["InputConfig"]["ECGFreq"]) +
ConfigParams.ENDSWITH_TXT))),
"Save_ECG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_SAVE_ECG_FILENAME +
ConfigParams.ENDSWITH_TXT)))
str(Config["InputConfig"]["ECGFreq"]) +
ConfigParams.ENDSWITH_TXT))),
"Save_Jpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_SAVE_JPEAK_FILENAME +
ConfigParams.ENDSWITH_TXT))),
"Save_Rpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(ConfigParams.PRECISELY_ALIGN_SAVE_RPEAK_FILENAME +
ConfigParams.ENDSWITH_TXT)))
},
"Coordinate": {
"BCG_front_1": 0,
@ -177,23 +199,35 @@ class SettingWindow(QMainWindow):
# 数据回显
self.ui.spinBox_input_freq_ECG.setValue(Config["InputConfig"]["ECGFreq"])
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(Config["Path"]["Input_orgBcg"])
self.ui.plainTextEdit_file_path_input_BCG.setPlainText(Config["Path"]["Input_BCG"])
self.ui.plainTextEdit_file_path_input_Jpeak.setPlainText(Config["Path"]["Input_Jpeak"])
self.ui.plainTextEdit_file_path_input_ECG.setPlainText(Config["Path"]["Input_ECG"])
self.ui.plainTextEdit_file_path_input_Rpeak.setPlainText(Config["Path"]["Input_Rpeak"])
self.ui.plainTextEdit_file_path_save_BCG_AlignInfo.setPlainText(Config["Path"]["Save_BCG_AlignInfo"])
self.ui.plainTextEdit_file_path_save_ECG_AlignInfo.setPlainText(Config["Path"]["Save_ECG_AlignInfo"])
self.ui.plainTextEdit_file_path_save_orgBcg.setPlainText(Config["Path"]["Save_orgBcg"])
self.ui.plainTextEdit_file_path_save_BCG.setPlainText(Config["Path"]["Save_BCG"])
self.ui.plainTextEdit_file_path_save_ECG.setPlainText(Config["Path"]["Save_ECG"])
self.ui.plainTextEdit_file_path_save_Jpeak.setPlainText(Config["Path"]["Save_Jpeak"])
self.ui.plainTextEdit_file_path_save_Rpeak.setPlainText(Config["Path"]["Save_Rpeak"])
def __write_config__(self):
# 从界面写入配置
Config["InputConfig"]["ECGFreq"] = self.ui.spinBox_input_freq_ECG.value()
Config["Path"]["Input_orgBcg"] = self.ui.plainTextEdit_file_path_input_orgBcg.toPlainText()
Config["Path"]["Input_BCG"] = self.ui.plainTextEdit_file_path_input_BCG.toPlainText()
Config["Path"]["Input_Jpeak"] = self.ui.plainTextEdit_file_path_input_Jpeak.toPlainText()
Config["Path"]["Input_ECG"] = self.ui.plainTextEdit_file_path_input_ECG.toPlainText()
Config["Path"]["Input_Rpeak"] = self.ui.plainTextEdit_file_path_input_Rpeak.toPlainText()
Config["Path"]["Save_BCG_AlignInfo"] = self.ui.plainTextEdit_file_path_save_BCG_AlignInfo.toPlainText()
Config["Path"]["Save_ECG_AlignInfo"] = self.ui.plainTextEdit_file_path_save_ECG_AlignInfo.toPlainText()
Config["Path"]["Save_orgBcg"] = self.ui.plainTextEdit_file_path_save_orgBcg.toPlainText()
Config["Path"]["Save_BCG"] = self.ui.plainTextEdit_file_path_save_BCG.toPlainText()
Config["Path"]["Save_ECG"] = self.ui.plainTextEdit_file_path_save_ECG.toPlainText()
Config["Path"]["Save_Jpeak"] = self.ui.plainTextEdit_file_path_save_Jpeak.toPlainText()
Config["Path"]["Save_Rpeak"] = self.ui.plainTextEdit_file_path_save_Rpeak.toPlainText()
# 保存配置到文件
self.config["InputConfig"]["ECGFreq"] = self.ui.spinBox_input_freq_ECG.value()
@ -209,6 +243,13 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.PRECISELY_ALIGN_INPUT_ORGBCG_FILENAME +
str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_BCG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
@ -223,6 +264,39 @@ class SettingWindow(QMainWindow):
Path(ConfigParams.PRECISELY_ALIGN_INPUT_ECG_FILENAME +
str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_orgBcg.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.PRECISELY_ALIGN_SAVE_ORGBCG_FILENAME +
str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_BCG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.PRECISELY_ALIGN_SAVE_BCG_FILENAME +
str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_ECG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.PRECISELY_ALIGN_SAVE_ECG_FILENAME +
str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_Jpeak.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.PRECISELY_ALIGN_SAVE_JPEAK_FILENAME +
ConfigParams.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_Rpeak.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.PRECISELY_ALIGN_SAVE_RPEAK_FILENAME +
ConfigParams.ENDSWITH_TXT))))
class MainWindow_precisely_align(QMainWindow):
@ -745,77 +819,190 @@ class MainWindow_precisely_align(QMainWindow):
if reply == QMessageBox.Yes:
PublicFunc.__disableAllButton__(self, ButtonState)
# 保存
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
status, info = self.data.save()
# 保存对齐信息
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/1)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.text_output(self.ui, "(1/6)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, 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/6)" + info, Constants.TIPS_TYPE_INFO)
# 保存切割后orgBcg
PublicFunc.progressbar_update(self, 2, 6, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG, 0)
total_rows = len(DataFrame(self.data.res_orgBcg.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save_orgBcg"], 'w') as f:
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)
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)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(2/6)" + info, Constants.TIPS_TYPE_INFO)
# 保存切割后BCG
PublicFunc.progressbar_update(self, 3, 6, Constants.PRECISELY_ALIGN_SAVING_RES_BCG, 0)
total_rows = len(DataFrame(self.data.res_BCG.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save_orgBcg"], 'w') as f:
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)
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)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(3/6)" + info, Constants.TIPS_TYPE_INFO)
# 保存切割后ECG
PublicFunc.progressbar_update(self, 4, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG, 0)
total_rows = len(DataFrame(self.data.cut_ECG.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save_ECG"], 'w') as f:
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)
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)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(4/6)" + info, Constants.TIPS_TYPE_INFO)
# 保存切割后J峰
PublicFunc.progressbar_update(self, 5, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK, 0)
total_rows = len(DataFrame(self.data.cut_Jpeak.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
with open(Config["Path"]["Save_Jpeak"], 'w') as f:
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)
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)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(5/6)" + info, Constants.TIPS_TYPE_INFO)
# 保存切割后R峰
PublicFunc.progressbar_update(self, 6, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK, 0)
total_rows = len(DataFrame(self.data.cut_Rpeak.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
with open(Config["Path"]["Save_Rpeak"], 'w') as f:
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)
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)
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.finish_operation(self, ButtonState)
def __update_coordinate__(self):
if self.data is not None:
if self.data.Jpeak is None or self.data.Rpeak is None:
PublicFunc.msgbox_output(self, Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Not_Exist"], Constants.MSGBOX_TYPE_ERROR)
return
try:
if self.data is not None:
if self.data.Jpeak is None or self.data.Rpeak is None:
PublicFunc.msgbox_output(self, Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Not_Exist"], Constants.MSGBOX_TYPE_ERROR)
return
sender = self.sender()
sender = self.sender()
if sender == self.ui.spinBox_BCG_front_JJIV_1:
if self.ui.spinBox_BCG_front_JJIV_1.value() >= len(self.data.Jpeak[:-2]):
self.ui.spinBox_BCG_front_JJIV_1.setValue(len(self.data.Jpeak[:-2]) - 1)
Config["IV_Coordinate"]["BCG_front_1"] = self.ui.spinBox_BCG_front_JJIV_1.value()
Config["Coordinate"]["BCG_front_1"] = self.data.Jpeak[:-2][self.ui.spinBox_BCG_front_JJIV_1.value()]
self.ui.spinBox_BCG_front_Signal_1.setValue(Config["Coordinate"]["BCG_front_1"])
elif sender == self.ui.spinBox_BCG_front_JJIV_2:
if self.ui.spinBox_BCG_front_JJIV_2.value() >= len(self.data.Jpeak[:-2]):
self.ui.spinBox_BCG_front_JJIV_2.setValue(len(self.data.Jpeak[:-2]) - 1)
Config["IV_Coordinate"]["BCG_front_2"] = self.ui.spinBox_BCG_front_JJIV_2.value()
Config["Coordinate"]["BCG_front_2"] = self.data.Jpeak[:-2][self.ui.spinBox_BCG_front_JJIV_2.value()]
self.ui.spinBox_BCG_front_Signal_2.setValue(Config["Coordinate"]["BCG_front_2"])
elif sender == self.ui.spinBox_BCG_back_JJIV_1:
if self.ui.spinBox_BCG_back_JJIV_1.value() >= len(self.data.Jpeak[:-2]):
self.ui.spinBox_BCG_back_JJIV_1.setValue(len(self.data.Jpeak[:-2]) - 1)
Config["IV_Coordinate"]["BCG_back_1"] = self.ui.spinBox_BCG_back_JJIV_1.value()
Config["Coordinate"]["BCG_back_1"] = self.data.Jpeak[:-2][self.ui.spinBox_BCG_back_JJIV_1.value()]
self.ui.spinBox_BCG_back_Signal_1.setValue(Config["Coordinate"]["BCG_back_1"])
elif sender == self.ui.spinBox_BCG_back_JJIV_2:
if self.ui.spinBox_BCG_back_JJIV_2.value() >= len(self.data.Jpeak[:-2]):
self.ui.spinBox_BCG_back_JJIV_2.setValue(len(self.data.Jpeak[:-2]) - 1)
Config["IV_Coordinate"]["BCG_back_2"] = self.ui.spinBox_BCG_back_JJIV_2.value()
Config["Coordinate"]["BCG_back_2"] = self.data.Jpeak[:-2][self.ui.spinBox_BCG_back_JJIV_2.value()]
self.ui.spinBox_BCG_back_Signal_2.setValue(Config["Coordinate"]["BCG_back_2"])
elif sender == self.ui.spinBox_ECG_front_RRIV_1:
if self.ui.spinBox_ECG_front_RRIV_1.value() >= len(self.data.Rpeak[:-2]):
self.ui.spinBox_ECG_front_RRIV_1.setValue(len(self.data.Rpeak[:-2]) - 1)
Config["IV_Coordinate"]["ECG_front_1"] = self.ui.spinBox_ECG_front_RRIV_1.value()
Config["Coordinate"]["ECG_front_1"] = self.data.Rpeak[:-2][self.ui.spinBox_ECG_front_RRIV_1.value()]
self.ui.spinBox_ECG_front_Signal_1.setValue(Config["Coordinate"]["ECG_front_1"])
elif sender == self.ui.spinBox_ECG_front_RRIV_2:
if self.ui.spinBox_ECG_front_RRIV_2.value() >= len(self.data.Rpeak[:-2]):
self.ui.spinBox_ECG_front_RRIV_2.setValue(len(self.data.Rpeak[:-2]) - 1)
Config["IV_Coordinate"]["ECG_front_2"] = self.ui.spinBox_ECG_front_RRIV_2.value()
Config["Coordinate"]["ECG_front_2"] = self.data.Rpeak[:-2][self.ui.spinBox_ECG_front_RRIV_2.value()]
self.ui.spinBox_ECG_front_Signal_2.setValue(Config["Coordinate"]["ECG_front_2"])
elif sender == self.ui.spinBox_ECG_back_RRIV_1:
if self.ui.spinBox_ECG_back_RRIV_1.value() >= len(self.data.Rpeak[:-2]):
self.ui.spinBox_ECG_back_RRIV_1.setValue(len(self.data.Rpeak[:-2]) - 1)
Config["IV_Coordinate"]["ECG_back_1"] = self.ui.spinBox_ECG_back_RRIV_1.value()
Config["Coordinate"]["ECG_back_1"] = self.data.Rpeak[:-2][self.ui.spinBox_ECG_back_RRIV_1.value()]
self.ui.spinBox_ECG_back_Signal_1.setValue(Config["Coordinate"]["ECG_back_1"])
elif sender == self.ui.spinBox_ECG_back_RRIV_2:
if self.ui.spinBox_ECG_back_RRIV_2.value() >= len(self.data.Rpeak[:-2]):
self.ui.spinBox_ECG_back_RRIV_2.setValue(len(self.data.Rpeak[:-2]) - 1)
Config["IV_Coordinate"]["ECG_back_2"] = self.ui.spinBox_ECG_back_RRIV_2.value()
Config["Coordinate"]["ECG_back_2"] = self.data.Rpeak[:-2][self.ui.spinBox_ECG_back_RRIV_2.value()]
self.ui.spinBox_ECG_back_Signal_2.setValue(Config["Coordinate"]["ECG_back_2"])
if sender == self.ui.spinBox_BCG_front_JJIV_1:
if self.ui.spinBox_BCG_front_JJIV_1.value() >= len(self.data.Jpeak[:-2]):
self.ui.spinBox_BCG_front_JJIV_1.setValue(len(self.data.Jpeak[:-2]) - 1)
Config["IV_Coordinate"]["BCG_front_1"] = self.ui.spinBox_BCG_front_JJIV_1.value()
Config["Coordinate"]["BCG_front_1"] = self.data.Jpeak[:-2][self.ui.spinBox_BCG_front_JJIV_1.value()]
self.ui.spinBox_BCG_front_Signal_1.setValue(Config["Coordinate"]["BCG_front_1"])
elif sender == self.ui.spinBox_BCG_front_JJIV_2:
if self.ui.spinBox_BCG_front_JJIV_2.value() >= len(self.data.Jpeak[:-2]):
self.ui.spinBox_BCG_front_JJIV_2.setValue(len(self.data.Jpeak[:-2]) - 1)
Config["IV_Coordinate"]["BCG_front_2"] = self.ui.spinBox_BCG_front_JJIV_2.value()
Config["Coordinate"]["BCG_front_2"] = self.data.Jpeak[:-2][self.ui.spinBox_BCG_front_JJIV_2.value()]
self.ui.spinBox_BCG_front_Signal_2.setValue(Config["Coordinate"]["BCG_front_2"])
elif sender == self.ui.spinBox_BCG_back_JJIV_1:
if self.ui.spinBox_BCG_back_JJIV_1.value() >= len(self.data.Jpeak[:-2]):
self.ui.spinBox_BCG_back_JJIV_1.setValue(len(self.data.Jpeak[:-2]) - 1)
Config["IV_Coordinate"]["BCG_back_1"] = self.ui.spinBox_BCG_back_JJIV_1.value()
Config["Coordinate"]["BCG_back_1"] = self.data.Jpeak[:-2][self.ui.spinBox_BCG_back_JJIV_1.value()]
self.ui.spinBox_BCG_back_Signal_1.setValue(Config["Coordinate"]["BCG_back_1"])
elif sender == self.ui.spinBox_BCG_back_JJIV_2:
if self.ui.spinBox_BCG_back_JJIV_2.value() >= len(self.data.Jpeak[:-2]):
self.ui.spinBox_BCG_back_JJIV_2.setValue(len(self.data.Jpeak[:-2]) - 1)
Config["IV_Coordinate"]["BCG_back_2"] = self.ui.spinBox_BCG_back_JJIV_2.value()
Config["Coordinate"]["BCG_back_2"] = self.data.Jpeak[:-2][self.ui.spinBox_BCG_back_JJIV_2.value()]
self.ui.spinBox_BCG_back_Signal_2.setValue(Config["Coordinate"]["BCG_back_2"])
elif sender == self.ui.spinBox_ECG_front_RRIV_1:
if self.ui.spinBox_ECG_front_RRIV_1.value() >= len(self.data.Rpeak[:-2]):
self.ui.spinBox_ECG_front_RRIV_1.setValue(len(self.data.Rpeak[:-2]) - 1)
Config["IV_Coordinate"]["ECG_front_1"] = self.ui.spinBox_ECG_front_RRIV_1.value()
Config["Coordinate"]["ECG_front_1"] = self.data.Rpeak[:-2][self.ui.spinBox_ECG_front_RRIV_1.value()]
self.ui.spinBox_ECG_front_Signal_1.setValue(Config["Coordinate"]["ECG_front_1"])
elif sender == self.ui.spinBox_ECG_front_RRIV_2:
if self.ui.spinBox_ECG_front_RRIV_2.value() >= len(self.data.Rpeak[:-2]):
self.ui.spinBox_ECG_front_RRIV_2.setValue(len(self.data.Rpeak[:-2]) - 1)
Config["IV_Coordinate"]["ECG_front_2"] = self.ui.spinBox_ECG_front_RRIV_2.value()
Config["Coordinate"]["ECG_front_2"] = self.data.Rpeak[:-2][self.ui.spinBox_ECG_front_RRIV_2.value()]
self.ui.spinBox_ECG_front_Signal_2.setValue(Config["Coordinate"]["ECG_front_2"])
elif sender == self.ui.spinBox_ECG_back_RRIV_1:
if self.ui.spinBox_ECG_back_RRIV_1.value() >= len(self.data.Rpeak[:-2]):
self.ui.spinBox_ECG_back_RRIV_1.setValue(len(self.data.Rpeak[:-2]) - 1)
Config["IV_Coordinate"]["ECG_back_1"] = self.ui.spinBox_ECG_back_RRIV_1.value()
Config["Coordinate"]["ECG_back_1"] = self.data.Rpeak[:-2][self.ui.spinBox_ECG_back_RRIV_1.value()]
self.ui.spinBox_ECG_back_Signal_1.setValue(Config["Coordinate"]["ECG_back_1"])
elif sender == self.ui.spinBox_ECG_back_RRIV_2:
if self.ui.spinBox_ECG_back_RRIV_2.value() >= len(self.data.Rpeak[:-2]):
self.ui.spinBox_ECG_back_RRIV_2.setValue(len(self.data.Rpeak[:-2]) - 1)
Config["IV_Coordinate"]["ECG_back_2"] = self.ui.spinBox_ECG_back_RRIV_2.value()
Config["Coordinate"]["ECG_back_2"] = self.data.Rpeak[:-2][self.ui.spinBox_ECG_back_RRIV_2.value()]
self.ui.spinBox_ECG_back_Signal_2.setValue(Config["Coordinate"]["ECG_back_2"])
except AttributeError:
pass
def reset_axes(self):
@ -900,6 +1087,8 @@ class MainWindow_precisely_align(QMainWindow):
return True, Constants.DRAWING_FINISHED
return False, Constants.DRAWING_FAILURE
def redraw_correlation_align(self, plot_element=None):
if plot_element is not None and plot_element["mode"] == "select":
@ -937,6 +1126,8 @@ class MainWindow_precisely_align(QMainWindow):
return True, Constants.DRAWING_FINISHED
return False, Constants.DRAWING_FAILURE
def toggle_home(self):
if self.ax0 is not None:
@ -1217,16 +1408,25 @@ class MainWindow_precisely_align(QMainWindow):
raise ValueError("this_line不存在")
self.__slot_btn_correlation_align__()
class Data:
def __init__(self):
self.file_path_input_orgBcg = Config["Path"]["Input_orgBcg"]
self.file_path_input_BCG = Config["Path"]["Input_BCG"]
self.file_path_input_Jpeak = Config["Path"]["Input_Jpeak"]
self.file_path_input_ECG = Config["Path"]["Input_ECG"]
self.file_path_input_Rpeak = Config["Path"]["Input_Rpeak"]
self.file_path_save_BCG_AlignInfo = Config["Path"]["Save_BCG_AlignInfo"]
self.file_path_save_ECG_AlignInfo = Config["Path"]["Save_ECG_AlignInfo"]
self.file_path_save_orgBcg = Config["Path"]["Save_orgBcg"]
self.file_path_save_BCG = Config["Path"]["Save_BCG"]
self.file_path_save_ECG = Config["Path"]["Save_ECG"]
self.file_path_save_Jpeak = Config["Path"]["Save_Jpeak"]
self.file_path_save_Rpeak = Config["Path"]["Save_Rpeak"]
self.raw_orgBcg = None
self.raw_BCG = None
self.Jpeak = None
self.Jpeak_y = None
@ -1234,10 +1434,11 @@ class Data:
self.Rpeak = None
self.Rpeak_y = None
self.cut_ECG = None
self.res_orgBcg = None
self.res_BCG = None
self.cut_Rpeak = None
self.cut_ECG = None
self.cut_Jpeak = None
self.cut_Rpeak = None
self.RRIs = None
self.JJIs = None
@ -1268,6 +1469,9 @@ class Data:
return False, Constants.INPUT_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Path_Not_Exist"]
try:
self.raw_orgBcg = read_csv(self.file_path_input_orgBcg,
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.raw_BCG = read_csv(self.file_path_input_BCG,
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
@ -1457,8 +1661,9 @@ class Data:
orgfs = Config["orgfs"]
off = Config["offset_anchor"]
self.cut_ECG = self.raw_ECG
self.res_orgBcg = self.raw_orgBcg
self.res_BCG = self.raw_BCG
self.cut_ECG = self.raw_ECG
self.cut_Rpeak = self.Rpeak
if off > 0:
@ -1469,10 +1674,12 @@ class Data:
self.cut_Rpeak = self.cut_Rpeak[idxs] - off
else:
self.res_BCG = self.res_BCG[-off:]
self.res_orgBcg = self.res_orgBcg[-off:]
anchor0[1] = anchor0[1] + off
anchor1[1] = anchor1[1] + off
self.res_BCG = resample(self.res_BCG, orgfs, Config["InputConfig"]["ECGFreq"])
self.res_orgBcg = resample(self.res_orgBcg, orgfs, Config["InputConfig"]["ECGFreq"])
anchor0[1] = round(int(anchor0[1]) * Config["InputConfig"]["ECGFreq"] / orgfs)
anchor1[1] = round(int(anchor1[1]) * Config["InputConfig"]["ECGFreq"] / orgfs)
@ -1486,12 +1693,14 @@ class Data:
self.cut_Rpeak = self.cut_Rpeak[idxs] - off
else:
self.res_BCG = self.res_BCG[-off:]
self.res_orgBcg = self.res_orgBcg[-off:]
anchor0[1] = anchor0[1] + off
anchor1[1] = anchor1[1] + off
datalen = np_min([len(self.cut_ECG), len(self.res_BCG)])
self.cut_ECG = self.cut_ECG[:datalen]
self.res_BCG = self.res_BCG[:datalen]
self.res_orgBcg = self.res_orgBcg[:datalen]
a = np_max([np_max(self.cut_ECG), np_max(self.res_BCG)])
b = np_min([np_min(self.cut_ECG), np_min(self.res_BCG)])
peak_ECG, _ = find_peaks(self.cut_ECG)
@ -1544,12 +1753,14 @@ class Data:
self.cut_Rpeak = self.cut_Rpeak[where(self.cut_Rpeak > off)[0]] - off
else:
self.res_BCG = self.res_BCG[-off:]
self.res_orgBcg = self.res_orgBcg[-off:]
anchor0[1] = anchor0[1] + off
anchor1[1] = anchor1[1] + off
datalen = np_min([len(self.cut_ECG), len(self.res_BCG)])
self.cut_ECG = self.cut_ECG[:datalen]
self.res_BCG = self.res_BCG[:datalen]
self.res_orgBcg = self.res_orgBcg[:datalen]
idxs = where(self.cut_Rpeak < datalen)[0]
self.cut_Rpeak = self.cut_Rpeak[idxs]
@ -1573,13 +1784,12 @@ class Data:
Config["backcut_index_BCG"] = backcut_index_BCG
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 True, f"{Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FINISHED}BCG前后段被切割的坐标值为[{frontcut_index_BCG}, {backcut_index_BCG}]ECG前后段被切割的坐标值为[{frontcut_index_ECG}, {backcut_index_ECG}]"
def save(self):
def save_alignInfo(self):
try:
save_data = {
@ -1613,13 +1823,73 @@ class Data:
}
}
save_data = [str(save_data)]
DataFrame(save_data).to_csv(self.file_path_save_BCG, index=False, header=False)
DataFrame(save_data).to_csv(self.file_path_save_ECG, index=False, header=False)
DataFrame(save_data).to_csv(self.file_path_save_BCG_AlignInfo, index=False, header=False)
DataFrame(save_data).to_csv(self.file_path_save_ECG_AlignInfo, index=False, header=False)
except Exception as e:
print(e)
return False, Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Save_Exception"]
return False, Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return True, Constants.SAVING_FINISHED
return True, 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"]
try:
chunk.to_csv(self.file_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 True, 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"]
try:
chunk.to_csv(self.file_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 True, 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"]
try:
chunk.to_csv(self.file_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 True, 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"]
try:
chunk.to_csv(self.file_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 True, 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"]
try:
chunk.to_csv(self.file_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 True, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FINISHED
class CustomNavigationToolbar(NavigationToolbar2QT):