From af59f9d257904eaa3d3e9242632f173b38b470f5 Mon Sep 17 00:00:00 2001 From: marques Date: Thu, 18 Dec 2025 21:20:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EOrgBCG=E5=81=8F=E7=A7=BB?= =?UTF-8?q?=E5=BE=AE=E8=B0=83=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=B2=97=E5=AF=B9=E9=BD=90=E4=BF=A1=E6=81=AF=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=92=8C=E8=AE=A1=E7=AE=97=E9=80=BB=E8=BE=91=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4UI=E5=B8=83=E5=B1=80=E5=92=8C=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_cut_pair_file.py | 97 +++++++++++------------ func/utils/Constants.py | 5 +- ui/MainWindow/MainWindow_cut_PAIR_FILE.py | 48 ++++++++--- ui/MainWindow/MainWindow_cut_PAIR_FILE.ui | 81 ++++++++++++------- 4 files changed, 141 insertions(+), 90 deletions(-) diff --git a/func/Module_cut_pair_file.py b/func/Module_cut_pair_file.py index 54581bf..1d8577b 100644 --- a/func/Module_cut_pair_file.py +++ b/func/Module_cut_pair_file.py @@ -1,6 +1,7 @@ +import traceback from ast import literal_eval from gc import collect -from math import floor +from math import floor, ceil from pathlib import Path from traceback import format_exc @@ -26,12 +27,14 @@ ButtonState = { "Default": { "checkBox_roughCut": False, "pushButton_deleteRoughCut": False, - "pushButton_execute": True + "pushButton_execute": True, + "spinBox_OrgBCGShift": False }, "Current": { "checkBox_roughCut": False, "pushButton_deleteRoughCut": False, - "pushButton_execute": True + "pushButton_execute": True, + "spinBox_OrgBCGShift": False } } @@ -84,6 +87,8 @@ class MainWindow_cut_PAIR_FILE(QMainWindow): self.ui.pushButton_execute.clicked.connect(self.__slot_btn_execute__) self.ui.checkBox_roughCut.stateChanged.connect(self.__change_approximate_align_mode__) + self.ui.spinBox_OrgBCGShift.setEnabled(False) + @overrides def closeEvent(self, event): @@ -131,6 +136,7 @@ class MainWindow_cut_PAIR_FILE(QMainWindow): ButtonState["Default"]["pushButton_deleteRoughCut"] = True self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys())) + self.ui.spinBox_OrgBCGShift.setEnabled(True) else: # ChannelInput 移除OrgBCGCHannelInput @@ -147,36 +153,7 @@ class MainWindow_cut_PAIR_FILE(QMainWindow): Config["ChannelSave"][key] = Config["ChannelSave"][key].replace("RoughCut", "Sync") ButtonState["Default"]["pushButton_deleteRoughCut"] = False self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys())) - - - def __get_approximately_align_info__(self): - time_bias = self.data.get_approximately_align_info() - if time_bias is not None: - info = "已成功获取粗对齐信息,时间偏移量为{:.3f}秒".format(time_bias) - PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO) - QApplication.processEvents() - return True - else: - info = "获取粗对齐信息失败,系统将尝试计算粗对齐信息" - PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_WARNING) - QApplication.processEvents() - - align_info = self.data.calc_approximately_align_info() - if align_info is not None: - info = "已成功计算粗对齐信息,切割点为:ECG前端去除{}样本点,ECG后端去除{}样本点,BCG前端去除{}样本点,BCG后端去除{}样本点".format( - align_info["cut_index"]["front_ECG"], - align_info["cut_index"]["back_ECG"], - align_info["cut_index"]["front_BCG"], - align_info["cut_index"]["back_BCG"] - ) - PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO) - QApplication.processEvents() - return True - else: - info = "计算粗对齐信息失败,无法进行后续操作" - PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR) - QApplication.processEvents() - return False + self.ui.spinBox_OrgBCGShift.setEnabled(False) def __slot_btn_execute__(self): @@ -196,6 +173,7 @@ class MainWindow_cut_PAIR_FILE(QMainWindow): else: if self.ui.checkBox_roughCut.isChecked(): Config["BCGFreq"] = self.data.freq["OrgBCG"] + Config["ECGFreq"] = self.data.freq["ECG"] PublicFunc.text_output(self.ui, "(1/5)" + result.info, Constants.TIPS_TYPE_INFO) PublicFunc.finish_operation(self, ButtonState) @@ -216,7 +194,7 @@ class MainWindow_cut_PAIR_FILE(QMainWindow): if self.ui.checkBox_roughCut.isChecked(): # 获取或计算粗对齐信息 PublicFunc.progressbar_update(self, 3, 5, Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO, 20) - result_approximate = self.__get_approximately_align_info__() + result_approximate = self.data.get_approximately_align_info() if not result_approximate: PublicFunc.msgbox_output(self, Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FAILURE, Constants.MSGBOX_TYPE_ERROR) PublicFunc.finish_operation(self, ButtonState) @@ -224,6 +202,15 @@ class MainWindow_cut_PAIR_FILE(QMainWindow): else: PublicFunc.text_output(self.ui, "(3/5)" + Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FINISHED, Constants.TIPS_TYPE_INFO) + result_approximate = self.data.calc_approximately_align_info(int(self.ui.spinBox_OrgBCGShift.value())) + if not result_approximate.status: + PublicFunc.text_output(self.ui, "(3/5)" + result_approximate.info, Constants.TIPS_TYPE_ERROR) + PublicFunc.msgbox_output(self, result_approximate.info, Constants.MSGBOX_TYPE_ERROR) + PublicFunc.finish_operation(self, ButtonState) + return + else: + PublicFunc.text_output(self.ui, "(3/5)" + result_approximate.info, Constants.TIPS_TYPE_INFO) + PublicFunc.finish_operation(self, ButtonState) # 切割数据 @@ -384,10 +371,11 @@ class Data: self.startTime = read_csv(Path(Config["Path"]["InputPSGFolder"]) / Path((Config["StartTime"] + Config["EndWith"]["StartTime"])), encoding=Params.UTF8_ENCODING, header=None).to_numpy().reshape(-1) - self.alignInfo = read_csv(Path(Config["Path"]["InputAlignInfo"]), - encoding=Params.UTF8_ENCODING, - header=None).to_numpy().reshape(-1) - self.alignInfo = literal_eval(self.alignInfo[0]) + if Path(Config["Path"]["InputAlignInfo"]).exists(): + self.alignInfo = read_csv(Path(Config["Path"]["InputAlignInfo"]), + encoding=Params.UTF8_ENCODING, + header=None).to_numpy().reshape(-1) + self.alignInfo = literal_eval(self.alignInfo[0]) except Exception as e: return Result().failure(info=Constants.INPUT_FAILURE + @@ -402,18 +390,20 @@ class Data: pos = df["pos"].values[-1] ApplyFrequency = df["ApplyFrequency"].values[-1] self.TimeBiasSecond = pos / ApplyFrequency - return self.TimeBiasSecond + return Result().success(info=Constants.INPUT_FINISHED) except Exception as e: self.TimeBiasSecond = 0 - return None + traceback.print_exc() + return Result().failure(info=Constants.INPUT_FAILURE + + Constants.FAILURE_REASON["Get_Approximately_Align_Info_Exception"] + + "\n" + format_exc()) - def calc_approximately_align_info(self): + def calc_approximately_align_info(self, OrgBCGShift=0): try: # 获取BCG长度 BCG_freq = Config["BCGFreq"] - BCG_second = len(self.raw["BCG"]) // BCG_freq - + BCG_second = len(self.raw["OrgBCG"]) // BCG_freq # 计算ECG长度 ECG_freq = Config["ECGFreq"] @@ -424,19 +414,19 @@ class Data: # 如果pos<0,表示BCG信号比ECG信号提前,需要在开头去除掉一部分BCG信号 if pos < 0: - front_BCG = floor(-pos) + front_BCG = ceil(-pos) + OrgBCGShift front_ECG = 0 else: - front_BCG = 0 - front_ECG = floor(pos) + front_BCG = 0 + OrgBCGShift + front_ECG = ceil(pos) # 计算结束位置 if (BCG_second - front_BCG) > (ECG_second - front_ECG): - back_ECG = ECG_second + front_ECG - back_BCG = back_ECG - floor(pos) + back_ECG = ECG_second + front_ECG - 1 + back_BCG = back_ECG - ceil(pos) else: - back_BCG = BCG_second + front_BCG - back_ECG = back_BCG + floor(pos) + back_BCG = BCG_second + front_BCG - 1 + back_ECG = back_BCG + ceil(pos) self.alignInfo = { "cut_index": { @@ -446,11 +436,14 @@ class Data: "back_BCG": back_BCG * BCG_freq } } - return self.alignInfo + return Result().success(info=Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_CALC_FINISHED) except Exception as e: - return None + traceback.print_exc() + print(e) + Result().failure(info=Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FAILURE + + Constants.FAILURE_REASON["Calculate_Approximately_Align_Info_Exception"] + "\n" + format_exc()) def cut_data(self): diff --git a/func/utils/Constants.py b/func/utils/Constants.py index a89c877..41074d6 100644 --- a/func/utils/Constants.py +++ b/func/utils/Constants.py @@ -183,7 +183,9 @@ class Constants: "res_BCG_Not_Exist": "(切割后BCG不存在)", "cut_ECG_Not_Exist": "(切割后ECG不存在)", "cut_Jpeak_Not_Exist": "(切割后J峰不存在)", - "cut_Rpeak_Not_Exist": "(切割后R峰不存在)" + "cut_Rpeak_Not_Exist": "(切割后R峰不存在)", + "Get_Approximately_Align_Info_Exception": "(获取粗对齐信息异常)", + "Calculate_Approximately_Align_Info_Exception": "(计算粗对齐信息异常)" } # 数据粗同步 @@ -368,6 +370,7 @@ class Constants: CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO: str = "正在获取粗对齐信息" CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FAILURE: str = "获取粗对齐信息失败" CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FINISHED: str = "获取粗对齐信息完成" + CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_CALC_FINISHED: str = "计算粗对齐信息完成" # 体动标注 diff --git a/ui/MainWindow/MainWindow_cut_PAIR_FILE.py b/ui/MainWindow/MainWindow_cut_PAIR_FILE.py index 1a622fd..cd1296f 100644 --- a/ui/MainWindow/MainWindow_cut_PAIR_FILE.py +++ b/ui/MainWindow/MainWindow_cut_PAIR_FILE.py @@ -116,13 +116,21 @@ class Ui_MainWindow_cut_PAIR_FILE(object): self.verticalLayout_5.addLayout(self.horizontalLayout_6) - self.horizontalLayout_7 = QHBoxLayout() - self.horizontalLayout_7.setObjectName(u"horizontalLayout_7") - self.label_7 = QLabel(self.groupBox_2) - self.label_7.setObjectName(u"label_7") - self.label_7.setFont(font) + self.gridLayout_3 = QGridLayout() + self.gridLayout_3.setObjectName(u"gridLayout_3") + self.label = QLabel(self.groupBox_2) + self.label.setObjectName(u"label") + self.label.setFont(font) - self.horizontalLayout_7.addWidget(self.label_7) + self.gridLayout_3.addWidget(self.label, 1, 0, 1, 1) + + self.spinBox = QSpinBox(self.groupBox_2) + self.spinBox.setObjectName(u"spinBox") + self.spinBox.setFont(font) + self.spinBox.setMinimum(1) + self.spinBox.setMaximum(1000000) + + self.gridLayout_3.addWidget(self.spinBox, 1, 1, 1, 1) self.spinBox_ECGFreq = QSpinBox(self.groupBox_2) self.spinBox_ECGFreq.setObjectName(u"spinBox_ECGFreq") @@ -130,12 +138,30 @@ class Ui_MainWindow_cut_PAIR_FILE(object): self.spinBox_ECGFreq.setMinimum(1) self.spinBox_ECGFreq.setMaximum(1000000) - self.horizontalLayout_7.addWidget(self.spinBox_ECGFreq) + self.gridLayout_3.addWidget(self.spinBox_ECGFreq, 0, 1, 1, 1) - self.horizontalLayout_7.setStretch(0, 1) - self.horizontalLayout_7.setStretch(1, 1) + self.label_7 = QLabel(self.groupBox_2) + self.label_7.setObjectName(u"label_7") + self.label_7.setFont(font) - self.verticalLayout_5.addLayout(self.horizontalLayout_7) + self.gridLayout_3.addWidget(self.label_7, 0, 0, 1, 1) + + self.label_3 = QLabel(self.groupBox_2) + self.label_3.setObjectName(u"label_3") + self.label_3.setFont(font2) + + self.gridLayout_3.addWidget(self.label_3, 2, 0, 1, 1) + + self.spinBox_OrgBCGShift = QSpinBox(self.groupBox_2) + self.spinBox_OrgBCGShift.setObjectName(u"spinBox_OrgBCGShift") + self.spinBox_OrgBCGShift.setFont(font) + self.spinBox_OrgBCGShift.setMinimum(-10000000) + self.spinBox_OrgBCGShift.setMaximum(10000000) + + self.gridLayout_3.addWidget(self.spinBox_OrgBCGShift, 2, 1, 1, 1) + + + self.verticalLayout_5.addLayout(self.gridLayout_3) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) @@ -224,7 +250,9 @@ class Ui_MainWindow_cut_PAIR_FILE(object): self.pushButton_deteleRougnCut.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u5220\u9664\u7c97\u5bf9\u9f50\u5207\u5272\u6587\u4ef6", None)) self.label_2.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u9700\u8981\u5207\u5272\u7684\u901a\u9053\u540d\uff1a", None)) self.label_6.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u9700\u8981\u6620\u5c04\u7684\u6807\u7b7e\uff1a", None)) + self.label.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"BCG\u539f\u59cb\u91c7\u6837\u7387\uff1a", None)) self.label_7.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u6570\u636e\u7cbe\u540c\u6b65\u65f6ECG\u7684\u91c7\u6837\u7387\uff1a", None)) + self.label_3.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u7c97\u5bf9\u9f50\u5fae\u8c03\u79d2\u6570(-\uff1a\u538b\u7535\u5de6\u79fb +\uff1a\u538b\u7535\u53f3\u79fb)", None)) self.label_show.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u70b9\u51fb\u6267\u884c\u4ee5\u5f00\u59cb...", None)) self.groupBox.setTitle(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u65e5\u5fd7", None)) self.pushButton_execute.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u6267\u884c", None)) diff --git a/ui/MainWindow/MainWindow_cut_PAIR_FILE.ui b/ui/MainWindow/MainWindow_cut_PAIR_FILE.ui index f021523..fbeedaf 100644 --- a/ui/MainWindow/MainWindow_cut_PAIR_FILE.ui +++ b/ui/MainWindow/MainWindow_cut_PAIR_FILE.ui @@ -125,33 +125,6 @@ - - - - - 12 - - - - 数据精同步时ECG的采样率: - - - - - - - - 12 - - - - 1 - - - 1000000 - - - @@ -179,6 +152,60 @@ + + + + + 12 + + + + 1 + + + 1000000 + + + + + + + + 12 + + + + 数据精同步时ECG的采样率: + + + + + + + + 10 + + + + 粗对齐微调秒数(-:压电左移 +:压电右移) + + + + + + + + 12 + + + + -10000000 + + + 10000000 + + +