精对齐添加通过粗对齐获取对应ECG区间的功能,优化相关提示信息

This commit is contained in:
marques
2025-06-04 15:35:48 +08:00
parent dfbc383706
commit 364d475d19
3 changed files with 216 additions and 51 deletions

View File

@ -1304,8 +1304,8 @@ class Data:
tho_seg_pos = argmax(tho_relate_seg) - len(orgBcg_seg)
abd_seg_pos = argmax(abd_relate_seg) - len(orgBcg_seg)
tho_bias_list.append(tho_seg_pos // temp_freq)
abd_bias_list.append(abd_seg_pos // temp_freq)
tho_bias_list.append(tho_seg_pos / temp_freq)
abd_bias_list.append(abd_seg_pos / temp_freq)
result = {

View File

@ -25,7 +25,6 @@ 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
Config = {
}
@ -191,7 +190,8 @@ class SettingWindow(QMainWindow):
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_input_approximately_align.setPlainText(Config["Path"]["Input_Approximately_Align"])
self.ui.plainTextEdit_file_path_input_approximately_align.setPlainText(
Config["Path"]["Input_Approximately_Align"])
self.ui.plainTextEdit_file_path_save_AlignInfo.setPlainText(Config["Path"]["Save_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"])
@ -209,7 +209,8 @@ class SettingWindow(QMainWindow):
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"]["Input_Approximately_Align"] = self.ui.plainTextEdit_file_path_input_approximately_align.toPlainText()
Config["Path"][
"Input_Approximately_Align"] = self.ui.plainTextEdit_file_path_input_approximately_align.toPlainText()
Config["Path"]["Save_AlignInfo"] = self.ui.plainTextEdit_file_path_save_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()
@ -488,7 +489,8 @@ class MainWindow_precisely_align(QMainWindow):
self.ax1.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
label="Start Line")
else:
self.ax0.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--", label="Start Line")
self.ax0.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
label="Start Line")
self.ax1.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
label="Start Line")
@ -496,7 +498,8 @@ class MainWindow_precisely_align(QMainWindow):
self.ax1.legend(loc=Constants.PLOT_UPPER_RIGHT)
self.canvas.draw()
return Result().success(info=Constants.DRAW_FINISHED)
elif sender == self.ui.pushButton_calculate_correlation and plot_element is not None and plot_element["mode"] == "init":
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)
self.ax0 = self.fig.add_subplot(self.gs[0])
@ -522,7 +525,8 @@ class MainWindow_precisely_align(QMainWindow):
self.ax0.stem(plot_element["front"]["corre"], markerfmt="C0.",
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_CORRE_RRIV_JJIV)
self.selected_point0, = self.ax0.plot(plot_element["front"]["shift"],
plot_element["front"]["corre"][plot_element["front"]["shift"]] + 1, 'v',
plot_element["front"]["corre"][plot_element["front"]["shift"]] + 1,
'v',
color=Constants.PLOT_COLOR_RED, picker=True, pickradius=5,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT)
self.ax0.plot(plot_element["front"]["corre"], 'o', color=Constants.PLOT_COLOR_BLUE,
@ -530,8 +534,10 @@ class MainWindow_precisely_align(QMainWindow):
self.ax1.stem(plot_element["front"]["RRIVs"], markerfmt="b.", linefmt=Constants.PLOT_COLOR_ORANGE,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
self.stem_black0 = self.ax1.stem(arange(plot_element["front"]["shift"],
plot_element["front"]["shift"] + len(plot_element["front"]["JJIVs"])),
plot_element["front"]["JJIVs"], markerfmt="ko", linefmt=Constants.PLOT_COLOR_GREEN,
plot_element["front"]["shift"] + len(
plot_element["front"]["JJIVs"])),
plot_element["front"]["JJIVs"], markerfmt="ko",
linefmt=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
self.ax2.set_title(
"back\ncorre_IIV: {}, corre_II: {}\nsame_sign_rate:{}, total_time_ratio: {}\nshift: {}, alignment offset: {} seconds\noffset_interval: {}, anchor_J: {}, anchor_R: {}".format(
@ -552,7 +558,8 @@ class MainWindow_precisely_align(QMainWindow):
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
self.stem_black1 = self.ax3.stem(arange(plot_element["back"]["shift"],
plot_element["back"]["shift"] + len(plot_element["back"]["JJIVs"])),
plot_element["back"]["JJIVs"], markerfmt="ko", linefmt=Constants.PLOT_COLOR_GREEN,
plot_element["back"]["JJIVs"], markerfmt="ko",
linefmt=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
@ -562,7 +569,8 @@ class MainWindow_precisely_align(QMainWindow):
self.canvas.draw()
return Result().success(info=Constants.DRAW_FINISHED)
elif sender == self.ui.pushButton_correlation_align or (plot_element is not None and plot_element["mode"] == "select"):
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)
self.ax4 = self.fig.add_subplot(self.gs[0])
@ -570,14 +578,20 @@ class MainWindow_precisely_align(QMainWindow):
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
self.ax4.set_title("offset correct")
self.ax4.plot(plot_element["cut_ECG"], color=Constants.PLOT_COLOR_GREEN, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_ECG)
self.ax4.plot(plot_element["res_BCG"], color=Constants.PLOT_COLOR_ORANGE, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_BCG)
self.ax4.plot([plot_element["anchor00"], plot_element["anchor00"]], [plot_element["b"], plot_element["a"]], 'k--')
self.ax4.plot([plot_element["anchor10"], plot_element["anchor10"]], [plot_element["b"], plot_element["a"]], 'k--')
self.ax4.plot(plot_element["cut_ECG"], color=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_ECG)
self.ax4.plot(plot_element["res_BCG"], color=Constants.PLOT_COLOR_ORANGE,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_BCG)
self.ax4.plot([plot_element["anchor00"], plot_element["anchor00"]], [plot_element["b"], plot_element["a"]],
'k--')
self.ax4.plot([plot_element["anchor10"], plot_element["anchor10"]], [plot_element["b"], plot_element["a"]],
'k--')
self.point0, = self.ax4.plot(plot_element["peak_ECG"], plot_element["cut_ECG"][plot_element["peak_ECG"]],
'o', markersize=3, color=Constants.PLOT_COLOR_BLUE, picker=True, pickradius=5, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RPEAK)
'o', markersize=3, color=Constants.PLOT_COLOR_BLUE, picker=True, pickradius=5,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RPEAK)
self.point1, = self.ax4.plot(plot_element["peak_BCG"], plot_element["res_BCG"][plot_element["peak_BCG"]],
'o', markersize=3, color=Constants.PLOT_COLOR_RED, picker=True, pickradius=5, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JPEAK)
'o', markersize=3, color=Constants.PLOT_COLOR_RED, picker=True, pickradius=5,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JPEAK)
self.ax4.legend(loc=Constants.PLOT_UPPER_RIGHT)
@ -591,10 +605,14 @@ class MainWindow_precisely_align(QMainWindow):
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
self.ax4.set_title("result preview")
self.ax4.plot(self.data.cut_ECG, color=Constants.PLOT_COLOR_GREEN, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_ECG)
self.ax4.plot(self.data.res_BCG, color=Constants.PLOT_COLOR_ORANGE, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_BCG)
self.ax4.plot(self.data.cut_Rpeak, self.data.cut_ECG[self.data.cut_Rpeak], 'v', color=Constants.PLOT_COLOR_BLUE, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RPEAK)
self.ax4.plot(self.data.cut_Jpeak, self.data.res_BCG[self.data.cut_Jpeak], 'v', color=Constants.PLOT_COLOR_RED, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JPEAK)
self.ax4.plot(self.data.cut_ECG, color=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_ECG)
self.ax4.plot(self.data.res_BCG, color=Constants.PLOT_COLOR_ORANGE,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_BCG)
self.ax4.plot(self.data.cut_Rpeak, self.data.cut_ECG[self.data.cut_Rpeak], 'v',
color=Constants.PLOT_COLOR_BLUE, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RPEAK)
self.ax4.plot(self.data.cut_Jpeak, self.data.res_BCG[self.data.cut_Jpeak], 'v',
color=Constants.PLOT_COLOR_RED, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JPEAK)
self.ax4.legend(loc=Constants.PLOT_UPPER_RIGHT)
@ -953,7 +971,8 @@ class MainWindow_precisely_align(QMainWindow):
try:
if self.data is not None:
if self.data.Jpeak is None or self.data.Rpeak is None:
PublicFunc.msgbox_output(self, Constants.FAILURE_REASON["Data_Not_Exist"], Constants.MSGBOX_TYPE_ERROR)
PublicFunc.msgbox_output(self, Constants.FAILURE_REASON["Data_Not_Exist"],
Constants.MSGBOX_TYPE_ERROR)
return
sender = self.sender()
@ -970,6 +989,13 @@ class MainWindow_precisely_align(QMainWindow):
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"])
PublicFunc.text_output(self.ui, Constants.CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE.format(
Config["Coordinate"]["BCG_front_1"],
Config["Coordinate"]["BCG_front_2"],
self.data.get_corresponding_interval(Config["Coordinate"]["BCG_front_1"]).data["new_point"],
self.data.get_corresponding_interval(Config["Coordinate"]["BCG_front_2"]).data["new_point"],
), Constants.TIPS_TYPE_INFO)
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)
@ -982,6 +1008,13 @@ class MainWindow_precisely_align(QMainWindow):
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"])
PublicFunc.text_output(self.ui, Constants.CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE.format(
Config["Coordinate"]["BCG_back_1"],
Config["Coordinate"]["BCG_back_2"],
self.data.get_corresponding_interval(Config["Coordinate"]["BCG_back_1"]).data["new_point"],
self.data.get_corresponding_interval(Config["Coordinate"]["BCG_back_2"]).data["new_point"],
), Constants.TIPS_TYPE_INFO)
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)
@ -994,6 +1027,17 @@ class MainWindow_precisely_align(QMainWindow):
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"])
PublicFunc.text_output(
self.ui, Constants.CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE.format(
Config["Coordinate"]["ECG_front_1"],
Config["Coordinate"]["ECG_front_2"],
self.data.get_corresponding_interval(Config["Coordinate"]["ECG_front_1"], bcg2ecg=False).data[
"new_point"],
self.data.get_corresponding_interval(Config["Coordinate"]["ECG_front_2"], bcg2ecg=False).data[
"new_point"],
), Constants.TIPS_TYPE_INFO
)
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)
@ -1006,7 +1050,19 @@ class MainWindow_precisely_align(QMainWindow):
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:
PublicFunc.text_output(
self.ui, Constants.CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE.format(
Config["Coordinate"]["ECG_back_1"],
Config["Coordinate"]["ECG_back_2"],
self.data.get_corresponding_interval(Config["Coordinate"]["ECG_back_1"], bcg2ecg=False).data[
"new_point"],
self.data.get_corresponding_interval(Config["Coordinate"]["ECG_back_2"], bcg2ecg=False).data[
"new_point"],
), Constants.TIPS_TYPE_INFO
)
except AttributeError as e:
print(e)
pass
def reset_axes(self):
@ -1063,12 +1119,15 @@ class MainWindow_precisely_align(QMainWindow):
plot_element["back"]["offset_interval"], plot_element["back"]["anchor_J"],
plot_element["back"]["anchor_R"]))
self.selected_point0, = self.ax0.plot(plot_element["front"]["shift"],
plot_element["front"]["corre"][plot_element["front"]["shift"]] + 1, 'v',
plot_element["front"]["corre"][plot_element["front"]["shift"]] + 1,
'v',
color=Constants.PLOT_COLOR_RED, picker=True, pickradius=5,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT)
self.stem_black0 = self.ax1.stem(arange(plot_element["front"]["shift"],
plot_element["front"]["shift"] + len(plot_element["front"]["JJIVs"])),
plot_element["front"]["JJIVs"], markerfmt="ko", linefmt=Constants.PLOT_COLOR_GREEN,
plot_element["front"]["shift"] + len(
plot_element["front"]["JJIVs"])),
plot_element["front"]["JJIVs"], markerfmt="ko",
linefmt=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
self.selected_point1, = self.ax2.plot(plot_element["back"]["shift"],
plot_element["back"]["corre"][plot_element["back"]["shift"]] + 1, 'v',
@ -1076,7 +1135,8 @@ class MainWindow_precisely_align(QMainWindow):
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT)
self.stem_black1 = self.ax3.stem(arange(plot_element["back"]["shift"],
plot_element["back"]["shift"] + len(plot_element["back"]["JJIVs"])),
plot_element["back"]["JJIVs"], markerfmt="ko", linefmt=Constants.PLOT_COLOR_GREEN,
plot_element["back"]["JJIVs"], markerfmt="ko",
linefmt=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
self.ax0.autoscale(False)
@ -1108,16 +1168,20 @@ class MainWindow_precisely_align(QMainWindow):
if len(self.data.correlation_align_point_match_ECG) > 0:
self.selected_point0, = self.ax4.plot(
[self.data.correlation_align_point_match_ECG[0], self.data.correlation_align_point_match_ECG[0]], [plot_element["b"], plot_element["a"]], 'b--')
[self.data.correlation_align_point_match_ECG[0], self.data.correlation_align_point_match_ECG[0]],
[plot_element["b"], plot_element["a"]], 'b--')
if len(self.data.correlation_align_point_match_ECG) == 2:
self.selected_point1, = self.ax4.plot(
[self.data.correlation_align_point_match_ECG[1], self.data.correlation_align_point_match_ECG[1]], [plot_element["b"], plot_element["a"]], 'b--')
[self.data.correlation_align_point_match_ECG[1],
self.data.correlation_align_point_match_ECG[1]], [plot_element["b"], plot_element["a"]], 'b--')
if len(self.data.correlation_align_point_match_BCG) > 0:
self.selected_point2, = self.ax4.plot(
[self.data.correlation_align_point_match_BCG[0], self.data.correlation_align_point_match_BCG[0]], [plot_element["b"], plot_element["a"]], 'r--')
[self.data.correlation_align_point_match_BCG[0], self.data.correlation_align_point_match_BCG[0]],
[plot_element["b"], plot_element["a"]], 'r--')
if len(self.data.correlation_align_point_match_BCG) == 2:
self.selected_point3, = self.ax4.plot(
[self.data.correlation_align_point_match_BCG[1], self.data.correlation_align_point_match_BCG[1]], [plot_element["b"], plot_element["a"]], 'r--')
[self.data.correlation_align_point_match_BCG[1],
self.data.correlation_align_point_match_BCG[1]], [plot_element["b"], plot_element["a"]], 'r--')
self.ax4.autoscale(False)
self.ax4.set_xlim(self.ax4_xlime)
@ -1267,11 +1331,30 @@ class MainWindow_precisely_align(QMainWindow):
Config["IV_Coordinate"]["BCG_front_2"] = indices[-1]
Config["Coordinate"]["BCG_front_1"] = self.data.Jpeak[:-2][indices[0]]
Config["Coordinate"]["BCG_front_2"] = self.data.Jpeak[:-2][indices[-1]]
PublicFunc.text_output(
self.ui,
Constants.CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE.format(
Config["Coordinate"]["BCG_front_1"],
Config["Coordinate"]["BCG_front_2"],
self.data.get_corresponding_interval(
Config["Coordinate"]["BCG_front_1"]).data["new_point"],
self.data.get_corresponding_interval(
Config["Coordinate"]["BCG_front_2"]).data["new_point"],
), Constants.TIPS_TYPE_INFO)
elif self.ui.radioButton_BCG_back.isChecked():
Config["IV_Coordinate"]["BCG_back_1"] = indices[0]
Config["IV_Coordinate"]["BCG_back_2"] = indices[-1]
Config["Coordinate"]["BCG_back_1"] = self.data.Jpeak[:-2][indices[0]]
Config["Coordinate"]["BCG_back_2"] = self.data.Jpeak[:-2][indices[-1]]
PublicFunc.text_output(
self.ui, Constants.CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE.format(
Config["Coordinate"]["BCG_back_1"],
Config["Coordinate"]["BCG_back_2"],
self.data.get_corresponding_interval(
Config["Coordinate"]["BCG_back_1"]).data["new_point"],
self.data.get_corresponding_interval(
Config["Coordinate"]["BCG_back_2"]).data["new_point"],
), Constants.TIPS_TYPE_INFO)
elif self.ui.radioButton_ECG_front.isChecked() or self.ui.radioButton_ECG_back.isChecked():
if rect_left < 0:
rect_left = 0
@ -1303,11 +1386,33 @@ class MainWindow_precisely_align(QMainWindow):
Config["IV_Coordinate"]["ECG_front_2"] = indices[-1]
Config["Coordinate"]["ECG_front_1"] = self.data.Rpeak[:-2][indices[0]]
Config["Coordinate"]["ECG_front_2"] = self.data.Rpeak[:-2][indices[-1]]
PublicFunc.text_output(
self.ui,
Constants.CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE.format(
Config["Coordinate"]["ECG_front_1"],
Config["Coordinate"]["ECG_front_2"],
self.data.get_corresponding_interval(
Config["Coordinate"]["ECG_front_1"], bcg2ecg=False).data[
"new_point"],
self.data.get_corresponding_interval(
Config["Coordinate"]["ECG_front_2"], bcg2ecg=False).data[
"new_point"],
), Constants.TIPS_TYPE_INFO)
elif self.ui.radioButton_ECG_back.isChecked():
Config["IV_Coordinate"]["ECG_back_1"] = indices[0]
Config["IV_Coordinate"]["ECG_back_2"] = indices[-1]
Config["Coordinate"]["ECG_back_1"] = self.data.Rpeak[:-2][indices[0]]
Config["Coordinate"]["ECG_back_2"] = self.data.Rpeak[:-2][indices[-1]]
PublicFunc.text_output(
self.ui, Constants.CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE.format(
Config["Coordinate"]["ECG_back_1"],
Config["Coordinate"]["ECG_back_2"],
self.data.get_corresponding_interval(
Config["Coordinate"]["ECG_back_1"], bcg2ecg=False).data["new_point"],
self.data.get_corresponding_interval(
Config["Coordinate"]["ECG_back_2"], bcg2ecg=False).data["new_point"],
), Constants.TIPS_TYPE_INFO
)
self.figToolbar.rect_start_x = None
self.figToolbar.rect_end_x = None
@ -1388,15 +1493,21 @@ class MainWindow_precisely_align(QMainWindow):
if this_line == self.point0:
if nm in self.data.correlation_align_point_match_ECG:
self.data.correlation_align_point_match_ECG = delete(self.data.correlation_align_point_match_ECG,
where(self.data.correlation_align_point_match_ECG == nm)[0])
where(
self.data.correlation_align_point_match_ECG == nm)[
0])
elif len(self.data.correlation_align_point_match_ECG) < 2:
self.data.correlation_align_point_match_ECG = append(self.data.correlation_align_point_match_ECG, nm)
self.data.correlation_align_point_match_ECG = append(self.data.correlation_align_point_match_ECG,
nm)
elif this_line == self.point1:
if nm in self.data.correlation_align_point_match_BCG:
self.data.correlation_align_point_match_BCG = delete(self.data.correlation_align_point_match_BCG,
where(self.data.correlation_align_point_match_BCG == nm)[0])
where(
self.data.correlation_align_point_match_BCG == nm)[
0])
elif len(self.data.correlation_align_point_match_BCG) < 2:
self.data.correlation_align_point_match_BCG = append(self.data.correlation_align_point_match_BCG, nm)
self.data.correlation_align_point_match_BCG = append(self.data.correlation_align_point_match_BCG,
nm)
else:
raise ValueError("this_line不存在")
self.__slot_btn_correlation_align__()
@ -1413,6 +1524,9 @@ class Data:
self.Rpeak = None
self.Rpeak_y = None
self.approximately_align_pos = None
self.approximately_align_estimated_freq = None
self.approximately_align_slope = None
self.approximately_align_intercept = None
self.BCG_early = None
self.res_orgBcg = None
@ -1552,6 +1666,12 @@ class Data:
else:
self.approximately_align_pos = 0
self.BCG_early = None
self.approximately_align_estimated_freq = df["estimate_freq"].values[-1]
self.approximately_align_slope = df["estimate_slope"].values[-1] / \
Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"]
self.approximately_align_intercept = df["estimate_intercept"].values[-1] * Config["InputConfig"]["UseFreq"]
except Exception:
self.approximately_align_pos = 0
@ -1565,7 +1685,8 @@ class Data:
if Config["InputConfig"]["orgBcgFreq"] != Config["InputConfig"]["UseFreq"]:
self.raw_orgBcg = resample(self.raw_orgBcg,
int(len(self.raw_orgBcg) *
(Config["InputConfig"]["UseFreq"] / Config["InputConfig"]["orgBcgFreq"])))
(Config["InputConfig"]["UseFreq"] / Config["InputConfig"][
"orgBcgFreq"])))
else:
return Result().success(info=Constants.RESAMPLE_NO_NEED)
except Exception as e:
@ -1605,8 +1726,10 @@ class Data:
try:
if mode == "init":
self.JJIs0_front = self.JJIs[Config["IV_Coordinate"]["BCG_front_1"]:Config["IV_Coordinate"]["BCG_front_2"]]
self.RRIs0_front = self.RRIs[Config["IV_Coordinate"]["ECG_front_1"]:Config["IV_Coordinate"]["ECG_front_2"]]
self.JJIs0_front = self.JJIs[
Config["IV_Coordinate"]["BCG_front_1"]:Config["IV_Coordinate"]["BCG_front_2"]]
self.RRIs0_front = self.RRIs[
Config["IV_Coordinate"]["ECG_front_1"]:Config["IV_Coordinate"]["ECG_front_2"]]
self.JJIVs_front = diff(self.JJIs0_front)
self.RRIVs_front = diff(self.RRIs0_front)
self.corre_front = correlate(self.RRIVs_front, self.JJIVs_front, 'valid')
@ -1656,7 +1779,8 @@ class Data:
}
except Exception as e:
return Result().failure(info=Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_FRONT +
Constants.FAILURE_REASON["Calculate_Correlation_Exception"] + "\n" + format_exc())
Constants.FAILURE_REASON[
"Calculate_Correlation_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_FRONT, data=result)
@ -1724,7 +1848,8 @@ class Data:
}
except Exception as e:
return Result().failure(info=Constants.PRECISELY_ALIGN_CALCULATE_FAILURE_BACK +
Constants.FAILURE_REASON["Calculate_Correlation_Exception"] + "\n" + format_exc())
Constants.FAILURE_REASON[
"Calculate_Correlation_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_BACK, data=result)
@ -1820,7 +1945,9 @@ class Data:
else:
self.correlation_align_point_match_ECG.sort()
self.correlation_align_point_match_BCG.sort()
off = round(((int(self.correlation_align_point_match_ECG[1]) - int(self.correlation_align_point_match_BCG[1])) + (int(self.correlation_align_point_match_ECG[0]) - int(self.correlation_align_point_match_BCG[0]))) / 2)
off = round(((int(self.correlation_align_point_match_ECG[1]) - int(
self.correlation_align_point_match_BCG[1])) + (int(self.correlation_align_point_match_ECG[0]) - int(
self.correlation_align_point_match_BCG[0]))) / 2)
anchor0 = [Config["front"]["anchor_R"], Config["front"]["anchor_J"]]
anchor1 = [Config["back"]["anchor_R"], Config["back"]["anchor_J"]]
@ -1854,8 +1981,10 @@ class Data:
self.cut_Jpeak.append(peaks[idx])
self.cut_Jpeak = asarray(self.cut_Jpeak).astype(int)
frontcut_index_BCG = int((self.argmax_BCG - np_argmax(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"]))
backcut_index_BCG = int(len(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"] + np_argmax(self.raw_BCG) - np_argmax(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"])
frontcut_index_BCG = int(
(self.argmax_BCG - np_argmax(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"]))
backcut_index_BCG = int(len(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"] + np_argmax(
self.raw_BCG) - np_argmax(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"])
frontcut_index_ECG = self.argmax_ECG - np_argmax(self.cut_ECG)
backcut_index_ECG = len(self.cut_ECG) + self.argmax_ECG - np_argmax(self.cut_ECG)
@ -1911,7 +2040,8 @@ class Data:
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FINISHED)
def save_res_orgBcg(self, chunk):
if (not Path(Config["Path"]["Save_OrgBCG"]).parent.exists()) or (not Path(Config["Path"]["Save_OrgBCG"]).parent.is_dir()):
if (not Path(Config["Path"]["Save_OrgBCG"]).parent.exists()) or (
not Path(Config["Path"]["Save_OrgBCG"]).parent.is_dir()):
Path(Config["Path"]["Save_OrgBCG"]).parent.mkdir(parents=True, exist_ok=True)
if Config["InputConfig"]["orgBcgFreq"] != Config["InputConfig"]["UseFreq"]:
@ -1932,7 +2062,8 @@ class Data:
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FINISHED)
def save_res_BCG(self, chunk):
if (not Path(Config["Path"]["Save_BCG"]).parent.exists()) or (not Path(Config["Path"]["Save_BCG"]).parent.is_dir()):
if (not Path(Config["Path"]["Save_BCG"]).parent.exists()) or (
not Path(Config["Path"]["Save_BCG"]).parent.is_dir()):
Path(Config["Path"]["Save_BCG"]).parent.mkdir(parents=True, exist_ok=True)
if self.res_BCG is None:
@ -1948,7 +2079,8 @@ class Data:
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FINISHED)
def save_cut_ECG(self, chunk):
if (not Path(Config["Path"]["Save_ECG"]).parent.exists()) or (not Path(Config["Path"]["Save_ECG"]).parent.is_dir()):
if (not Path(Config["Path"]["Save_ECG"]).parent.exists()) or (
not Path(Config["Path"]["Save_ECG"]).parent.is_dir()):
Path(Config["Path"]["Save_ECG"]).parent.mkdir(parents=True, exist_ok=True)
if self.cut_ECG is None:
@ -1964,7 +2096,8 @@ class Data:
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FINISHED)
def save_Jpeak(self, chunk):
if (not Path(Config["Path"]["Save_ECG"]).parent.exists()) or (not Path(Config["Path"]["Save_ECG"]).parent.is_dir()):
if (not Path(Config["Path"]["Save_ECG"]).parent.exists()) or (
not Path(Config["Path"]["Save_ECG"]).parent.is_dir()):
Path(Config["Path"]["Save_ECG"]).parent.mkdir(parents=True, exist_ok=True)
if self.cut_Jpeak is None:
@ -1980,7 +2113,8 @@ class Data:
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FINISHED)
def save_Rpeak(self, chunk):
if (not Path(Config["Path"]["Save_Rpeak"]).parent.exists()) or (not Path(Config["Path"]["Save_Rpeak"]).parent.is_dir()):
if (not Path(Config["Path"]["Save_Rpeak"]).parent.exists()) or (
not Path(Config["Path"]["Save_Rpeak"]).parent.is_dir()):
Path(Config["Path"]["Save_Rpeak"]).parent.mkdir(parents=True, exist_ok=True)
if self.cut_Rpeak is None:
@ -1995,6 +2129,30 @@ class Data:
return Result().success(info=Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FINISHED)
def get_corresponding_interval(self, point, bcg2ecg=True):
try:
if self.BCG_early:
pos = -self.approximately_align_pos
else:
pos = self.approximately_align_pos
if bcg2ecg:
new_point = point / self.approximately_align_estimated_freq + pos - self.approximately_align_intercept
else:
new_point = (point - pos + self.approximately_align_intercept) * self.approximately_align_estimated_freq
result = {
"new_point": int(new_point)
}
except Exception as e:
return Result().failure(info=Constants.PRECISELY_ALIGN_GET_CORRESPONDING_INTERVAL_FAILURE +
Constants.FAILURE_REASON[
"Get_Corresponding_Interval_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.PRECISELY_ALIGN_GET_CORRESPONDING_INTERVAL_FINISHED, data=result)
class CustomNavigationToolbar(NavigationToolbar2QT):

View File

@ -46,6 +46,8 @@ class Constants:
SAVE_FINISHED: str = "保存完成"
SAVE_FAILURE: str = "保存失败"
CORRESPONDING_INTERVAL_PROMOTE_TEMPLATE: str = "经粗对齐计算BCG({},{})对应的ECG约区间为({},{})"
OPERATION_FINISHED: str = "操作完成"
OPERATION_FAILURE: str = "操作失败"
OPERATION_CANCELED: str = "操作取消"
@ -125,6 +127,7 @@ class Constants:
"Predict_Exception": "(预测异常)",
"Read_Model_Exception": "(读取模型异常)",
"Calculate_Correlation_Value_Equal": "(计算相关性参数相同)",
"Get_Corresponding_Interval_Exception": "(获取对应区间异常)",
"Calculate_Correlation_JJIVRange_too_Large": "计算相关性JJIV范围大于RRIV范围",
"Calculate_Correlation_Exception": "(计算相关性异常)",
"Correlation_Align_Exception": "(处理相关对齐异常)",
@ -258,6 +261,10 @@ class Constants:
PRECISELY_ALIGN_CALCULATE_FINISHED_BACK: str = "计算后段相关性完成"
PRECISELY_ALIGN_CALCULATE_FAILURE_BACK: str = "计算后段相关性失败"
PRECISELY_ALIGN_GET_CORRESPONDING_INTERVAL : str = "正在获取对应区间"
PRECISELY_ALIGN_GET_CORRESPONDING_INTERVAL_FAILURE : str = "获取对应区间失败"
PRECISELY_ALIGN_GET_CORRESPONDING_INTERVAL_FINISHED : str = "获取对应区间完成"
PRECISELY_ALIGN_ALIGNING_CORRELATION: str = "正在处理相关对齐"
PRECISELY_ALIGN_ALIGN_CORRELATION_FINISHED: str = "处理相关对齐完成"
PRECISELY_ALIGN_ALIGN_CORRELATION_FAILURE: str = "处理相关对齐失败"