From 99d355be6b3be978ed19602b61ac650961d73fa2 Mon Sep 17 00:00:00 2001 From: marques <20172333133@m.scnu.edu.cn> Date: Wed, 21 May 2025 21:58:39 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=A3=E7=82=B9?= =?UTF-8?q?=E5=9B=BE=E7=BB=98=E5=88=B6=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=9D=90?= =?UTF-8?q?=E6=A0=87=E8=BD=B4=E6=A0=87=E7=AD=BE=E5=92=8C=E9=9B=B6=E6=B0=B4?= =?UTF-8?q?=E5=B9=B3=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_approximately_align.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/func/Module_approximately_align.py b/func/Module_approximately_align.py index 0c85386..e585dd2 100644 --- a/func/Module_approximately_align.py +++ b/func/Module_approximately_align.py @@ -896,10 +896,16 @@ class MainWindow_approximately_align(QMainWindow): ax1 = self.fig.add_subplot(211) ax1.scatter(linspace(epoch_min, epoch_max, len(tho_bias_list)), tho_bias_list, alpha=0.2) + ax1.axhline(y=0, color='red', linestyle='--', alpha=0.3) + ax1.set_xlabel("Epoch") + ax1.set_ylabel("Tho Bias / s") ax1.set_title("THO") ax2 = self.fig.add_subplot(212) ax2.scatter(linspace(epoch_min, epoch_max, len(abd_bias_list)), abd_bias_list, alpha=0.2) + ax2.axhline(y=0, color='red', linestyle='--', alpha=0.3) + ax2.set_xlabel("Epoch") + ax2.set_ylabel("Abd Bias / s") ax2.set_title("ABD") self.fig.canvas.draw() @@ -922,8 +928,7 @@ class Data: self.processed_downsample_orgBcg = None self.processed_downsample_Tho = None self.processed_downsample_Abd = None - self.relate_list = None - self.relate_point = None + def open_file(self): if Path(Config["Path"]["Input_orgBcg"]).is_file(): -- 2.43.0 From e200c2a488d89f2f556786b561f6449c323056f4 Mon Sep 17 00:00:00 2001 From: marques <20172333133@m.scnu.edu.cn> Date: Mon, 2 Jun 2025 20:19:40 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=87=87=E6=A0=B7?= =?UTF-8?q?=E7=8E=87=E4=BC=B0=E8=AE=A1=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=95=8C=E9=9D=A2=E5=B8=83=E5=B1=80=E5=92=8C=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_approximately_align.py | 132 ++++++++++-- func/utils/ConfigParams.py | 1 + func/utils/Constants.py | 4 + .../MainWindow_approximately_align.py | 113 ++++++---- .../MainWindow_approximately_align.ui | 194 +++++++++++------- 5 files changed, 309 insertions(+), 135 deletions(-) diff --git a/func/Module_approximately_align.py b/func/Module_approximately_align.py index e585dd2..2636c13 100644 --- a/func/Module_approximately_align.py +++ b/func/Module_approximately_align.py @@ -12,7 +12,7 @@ from overrides import overrides from pandas import read_csv, DataFrame from scipy.signal import find_peaks, resample, butter, sosfiltfilt, correlate from yaml import dump, load, FullLoader - +from sklearn.linear_model import TheilSenRegressor from func.utils.PublicFunc import PublicFunc from func.utils.Constants import Constants, ConfigParams from func.utils.Result import Result @@ -44,7 +44,9 @@ ButtonState = { "radioButton_PABD": False, "radioButton_NTHO": False, "radioButton_NABD": False, - "radioButton_custom": False + "radioButton_custom": False, + "radioButton_freqTHO": False, + "radioButton_freqABD": False, }, "Current": { "pushButton_input_setting": True, @@ -65,7 +67,9 @@ ButtonState = { "radioButton_PABD": False, "radioButton_NTHO": False, "radioButton_NABD": False, - "radioButton_custom": False + "radioButton_custom": False, + "radioButton_freqTHO": False, + "radioButton_freqABD": False, } } @@ -259,6 +263,8 @@ class MainWindow_approximately_align(QMainWindow): self.ui.radioButton_PABD.clicked.connect(self.__enableAlign__) self.ui.radioButton_NABD.clicked.connect(self.__enableAlign__) self.ui.radioButton_custom.clicked.connect(self.__enableAlign__) + self.ui.radioButton_freqTHO.clicked.connect(self.__EstimateFrequencySelect__) + self.ui.radioButton_freqABD.clicked.connect(self.__EstimateFrequencySelect__) @overrides @@ -305,6 +311,11 @@ class MainWindow_approximately_align(QMainWindow): self.ui.radioButton_NABD.setText("备选4") self.ui.radioButton_NTHO.setText("备选2") self.ui.spinBox_SelectEpoch.setMinimum(0) + self.ui.radioButton_freqABD.setChecked(False) + self.ui.radioButton_freqTHO.setChecked(False) + self.ui.radioButton_freqTHO.setText("备选1") + self.ui.radioButton_freqABD.setText("备选2") + def __plot__(self, *args, **kwargs): sender = self.sender() @@ -328,7 +339,7 @@ class MainWindow_approximately_align(QMainWindow): elif sender == self.ui.radioButton_custom: result = self.DrawPicTryAlign() elif sender == self.ui.pushButton_ChangeView: - result = self.DrawAlignScatter() + result = self.DrawAlignScatter(*args, **kwargs) elif sender == self.ui.pushButton_JUMP: result = self.DrawPicByEpoch(*args, **kwargs) elif sender == self.ui.pushButton_EM1: @@ -570,7 +581,39 @@ class MainWindow_approximately_align(QMainWindow): # 绘图 PublicFunc.progressbar_update(self, 1, 1, Constants.DRAWING_DATA, 0) - result = self.__plot__() + response = self.data.get_corr_by_epoch() + epoch_min = response.data["epoch_min"] + epoch_max = response.data["epoch_max"] + tho_bias_list = response.data["tho_bias_list"] + abd_bias_list = response.data["abd_bias_list"] + + response = self.data.estimate_frequency(tho_bias_list) + tho_y = response.data["estimate_y"] + tho_frequency = response.data["frequency"] + tho_slope = response.data["slope"] + tho_intercept = response.data["intercept"] + response = self.data.estimate_frequency(abd_bias_list) + abd_y = response.data["estimate_y"] + abd_frequency = response.data["frequency"] + abd_slope = response.data["slope"] + abd_intercept = response.data["intercept"] + result = self.__plot__(epoch_min, epoch_max, tho_bias_list, abd_bias_list, tho_y, abd_y, + tho_frequency, abd_frequency) + Config["estimate"] = {} + Config["estimate"]["tho_frequency"] = tho_frequency + Config["estimate"]["tho_slope"] = tho_slope + Config["estimate"]["tho_intercept"] = tho_intercept + + Config["estimate"]["abd_frequency"] = abd_frequency + Config["estimate"]["abd_slope"] = abd_slope + Config["estimate"]["abd_intercept"] = abd_intercept + + self.ui.radioButton_freqTHO.setText(str(Config["estimate"]["tho_frequency"])) + self.ui.radioButton_freqABD.setText(str(Config["estimate"]["abd_frequency"])) + ButtonState["Current"]["radioButton_freqTHO"] = True + ButtonState["Current"]["radioButton_freqABD"] = True + + 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) @@ -599,6 +642,25 @@ class MainWindow_approximately_align(QMainWindow): PublicFunc.finish_operation(self, ButtonState) + def __EstimateFrequencySelect__(self): + PublicFunc.__disableAllButton__(self, ButtonState) + if self.ui.radioButton_freqTHO.isChecked(): + frequency = Config["estimate"]["tho_frequency"] + Config["estimate_freq"] = frequency + Config["estimate_slope"] = Config["estimate"]["tho_slope"] + Config["estimate_intercept"] = Config["estimate"]["tho_intercept"] + elif self.ui.radioButton_freqABD.isChecked(): + frequency = Config["estimate"]["abd_frequency"] + Config["estimate_freq"] = frequency + Config["estimate_slope"] = Config["estimate"]["abd_slope"] + Config["estimate_intercept"] = Config["estimate"]["abd_intercept"] + else: + return + + ButtonState["Current"]["pushButton_save"] = True + PublicFunc.finish_operation(self, ButtonState) + + def __EpochChange__(self): # 获取当前值 value = self.ui.spinBox_SelectEpoch.value() @@ -682,7 +744,6 @@ class MainWindow_approximately_align(QMainWindow): ButtonState["Current"]["pushButton_EP1"] = True ButtonState["Current"]["pushButton_EP10"] = True ButtonState["Current"]["pushButton_EP100"] = True - ButtonState["Current"]["pushButton_save"] = True ButtonState["Current"]["pushButton_ChangeView"] = True PublicFunc.finish_operation(self, ButtonState) @@ -886,27 +947,26 @@ class MainWindow_approximately_align(QMainWindow): # 返回图片以便存到QPixImage return Result().success(info=Constants.DRAW_FINISHED) - def DrawAlignScatter(self): + def DrawAlignScatter(self, epoch_min, epoch_max, tho_bias_list, abd_bias_list, tho_y, abd_y, + tho_frequency, abd_frequency): try: - response = self.data.get_corr_by_epoch() - epoch_min = response.data["epoch_min"] - epoch_max = response.data["epoch_max"] - tho_bias_list = response.data["tho_bias_list"] - abd_bias_list = response.data["abd_bias_list"] - ax1 = self.fig.add_subplot(211) ax1.scatter(linspace(epoch_min, epoch_max, len(tho_bias_list)), tho_bias_list, alpha=0.2) + ax1.plot(linspace(epoch_min, epoch_max, len(tho_bias_list)), tho_y, color='orange', label=f"THO Frequency: {tho_frequency} Hz") ax1.axhline(y=0, color='red', linestyle='--', alpha=0.3) ax1.set_xlabel("Epoch") ax1.set_ylabel("Tho Bias / s") ax1.set_title("THO") + ax1.legend() ax2 = self.fig.add_subplot(212) ax2.scatter(linspace(epoch_min, epoch_max, len(abd_bias_list)), abd_bias_list, alpha=0.2) + ax2.plot(linspace(epoch_min, epoch_max, len(abd_bias_list)), abd_y, color='orange', label=f"ABD Frequency: {abd_frequency} Hz") ax2.axhline(y=0, color='red', linestyle='--', alpha=0.3) ax2.set_xlabel("Epoch") ax2.set_ylabel("Abd Bias / s") ax2.set_title("ABD") + ax2.legend() self.fig.canvas.draw() return Result().success(info=Constants.DRAW_FINISHED) @@ -979,8 +1039,18 @@ class Data: try: pos = Config["pos"] ApplyFrequency = Config["ApplyFrequency"] + estimate_freq = Config["estimate_freq"] + estimate_slope = Config["estimate_slope"] + estimate_intercept = Config["estimate_intercept"] # 保存到csv中 - df = DataFrame({"pos": [pos], "epoch": [epoch], "ApplyFrequency": [ApplyFrequency]}) + df = DataFrame({"pos": [pos], + "epoch": [epoch], + "ApplyFrequency": [ApplyFrequency], + "estimate_freq": [estimate_freq], + "estimate_slope": [estimate_slope], + "estimate_intercept": [estimate_intercept] + }) + df.to_csv(Path(Config["Path"]["Save"]), mode="w", header=True, index=False) except Exception as e: return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON[ @@ -1221,6 +1291,7 @@ class Data: epoch_min = response.data["epoch_min"] epoch_max = response.data["epoch_max"] + epoch_second = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"] temp_freq = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"] window_epoch = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["CorrByEpoch"]["window_epoch"] @@ -1231,8 +1302,8 @@ class Data: pos = Config["pos"] * temp_freq // Config["ApplyFrequency"] for epoch in range(epoch_min, epoch_max): - SP = epoch * 30 * temp_freq - EP = (epoch + window_epoch) * 30 * temp_freq + SP = epoch * epoch_second * temp_freq + EP = (epoch + window_epoch) * epoch_second * temp_freq tho_seg = self.processed_Tho[SP:EP] abd_seg = self.processed_Abd[SP:EP] @@ -1260,3 +1331,32 @@ class Data: "Get_Corr_By_Epoch_Exception"] + "\n" + format_exc()) return Result().success(info=Constants.APPROXIMATELY_EPOCH_GET_FINISHED, data=result) + + @staticmethod + def estimate_frequency(bias_list): + try: + epoch_second = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"] + temp_freq = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"] + + # 生成线性数据 + X = linspace(0, len(bias_list), len(bias_list)).reshape(-1, 1) + y = bias_list + + theilsen = TheilSenRegressor() + theilsen.fit(X, y) + slope = theilsen.coef_[0] + frequency = 1 - slope / epoch_second / temp_freq if slope != 0 else float('inf') + + theilsen_y = theilsen.predict(X) + + return Result().success(info=Constants.APPROXIMATELY_ESTIMATE_FREQUENCY_FINISHED, + data={"estimate_y": theilsen_y, + "frequency": frequency, + "slope": slope, + "intercept": theilsen.intercept_}, + ) + except Exception as e: + return Result().failure( + info=Constants.APPROXIMATELY_ESTIMATE_FREQUENCY_FAILURE + Constants.FAILURE_REASON[ + "Estimate_Frequency_Exception"] + "\n" + format_exc()) + diff --git a/func/utils/ConfigParams.py b/func/utils/ConfigParams.py index 254fa36..0b56844 100644 --- a/func/utils/ConfigParams.py +++ b/func/utils/ConfigParams.py @@ -85,6 +85,7 @@ class ConfigParams: "BandPassHigh": 0.7 }, "Multiple_Factor":100, + "Second_PerEpoch": 30, "CorrByEpoch": { "window_epoch": 6 diff --git a/func/utils/Constants.py b/func/utils/Constants.py index 717a91b..08b8006 100644 --- a/func/utils/Constants.py +++ b/func/utils/Constants.py @@ -182,6 +182,10 @@ class Constants: APPROXIMATELY_EPOCH_GET_FINISHED: str = "获取epoch完成" APPROXIMATELY_EPOCH_GET_FAILURE: str = "获取epoch失败" + APPROXIMATELY_ESTIMATE_FREQUENCY_CALCULATING: str = "正在估计采样率" + APPROXIMATELY_ESTIMATE_FREQUENCY_FINISHED: str = "估计采样率完成" + APPROXIMATELY_ESTIMATE_FREQUENCY_FAILURE: str = "估计采样率失败" + # 预处理 PREPROCESS_PLOT_LABEL_ORIGINAL_DATA: str = "Original_Data" PREPROCESS_PLOT_LABEL_PROCESSED_DATA: str = "Processed_Data" diff --git a/ui/MainWindow/MainWindow_approximately_align.py b/ui/MainWindow/MainWindow_approximately_align.py index c03e1c9..9368fe4 100644 --- a/ui/MainWindow/MainWindow_approximately_align.py +++ b/ui/MainWindow/MainWindow_approximately_align.py @@ -317,11 +317,12 @@ class Ui_MainWindow_approximately_align(object): self.groupBox_align_position.setObjectName(u"groupBox_align_position") self.gridLayout_2 = QGridLayout(self.groupBox_align_position) self.gridLayout_2.setObjectName(u"gridLayout_2") - self.radioButton_PABD = QRadioButton(self.groupBox_align_position) - self.radioButton_PABD.setObjectName(u"radioButton_PABD") - self.radioButton_PABD.setFont(font1) + self.pushButton_ChangeView = QPushButton(self.groupBox_align_position) + self.pushButton_ChangeView.setObjectName(u"pushButton_ChangeView") + self.pushButton_ChangeView.setMinimumSize(QSize(0, 30)) + self.pushButton_ChangeView.setFont(font1) - self.gridLayout_2.addWidget(self.radioButton_PABD, 1, 2, 1, 1) + self.gridLayout_2.addWidget(self.pushButton_ChangeView, 0, 2, 1, 1) self.radioButton_NTHO = QRadioButton(self.groupBox_align_position) self.radioButton_NTHO.setObjectName(u"radioButton_NTHO") @@ -329,12 +330,37 @@ class Ui_MainWindow_approximately_align(object): self.gridLayout_2.addWidget(self.radioButton_NTHO, 1, 1, 1, 1) + self.radioButton_PTHO = QRadioButton(self.groupBox_align_position) + self.radioButton_PTHO.setObjectName(u"radioButton_PTHO") + self.radioButton_PTHO.setFont(font1) + + self.gridLayout_2.addWidget(self.radioButton_PTHO, 1, 0, 1, 1) + self.radioButton_custom = QRadioButton(self.groupBox_align_position) self.radioButton_custom.setObjectName(u"radioButton_custom") self.radioButton_custom.setFont(font1) self.gridLayout_2.addWidget(self.radioButton_custom, 2, 1, 1, 1) + self.radioButton_PABD = QRadioButton(self.groupBox_align_position) + self.radioButton_PABD.setObjectName(u"radioButton_PABD") + self.radioButton_PABD.setFont(font1) + + self.gridLayout_2.addWidget(self.radioButton_PABD, 1, 2, 1, 1) + + self.pushButton_GetPos = QPushButton(self.groupBox_align_position) + self.pushButton_GetPos.setObjectName(u"pushButton_GetPos") + self.pushButton_GetPos.setMinimumSize(QSize(0, 30)) + self.pushButton_GetPos.setFont(font1) + + self.gridLayout_2.addWidget(self.pushButton_GetPos, 0, 0, 1, 1) + + self.radioButton_NABD = QRadioButton(self.groupBox_align_position) + self.radioButton_NABD.setObjectName(u"radioButton_NABD") + self.radioButton_NABD.setFont(font1) + + self.gridLayout_2.addWidget(self.radioButton_NABD, 2, 0, 1, 1) + self.spinBox_custom = QSpinBox(self.groupBox_align_position) self.spinBox_custom.setObjectName(u"spinBox_custom") self.spinBox_custom.setMinimumSize(QSize(90, 0)) @@ -346,35 +372,38 @@ class Ui_MainWindow_approximately_align(object): self.gridLayout_2.addWidget(self.spinBox_custom, 2, 2, 1, 1) - self.radioButton_PTHO = QRadioButton(self.groupBox_align_position) - self.radioButton_PTHO.setObjectName(u"radioButton_PTHO") - self.radioButton_PTHO.setFont(font1) - - self.gridLayout_2.addWidget(self.radioButton_PTHO, 1, 0, 1, 1) - - self.radioButton_NABD = QRadioButton(self.groupBox_align_position) - self.radioButton_NABD.setObjectName(u"radioButton_NABD") - self.radioButton_NABD.setFont(font1) - - self.gridLayout_2.addWidget(self.radioButton_NABD, 2, 0, 1, 1) - - self.pushButton_GetPos = QPushButton(self.groupBox_align_position) - self.pushButton_GetPos.setObjectName(u"pushButton_GetPos") - self.pushButton_GetPos.setMinimumSize(QSize(0, 30)) - self.pushButton_GetPos.setFont(font1) - - self.gridLayout_2.addWidget(self.pushButton_GetPos, 0, 0, 1, 1) - - self.pushButton_ChangeView = QPushButton(self.groupBox_align_position) - self.pushButton_ChangeView.setObjectName(u"pushButton_ChangeView") - self.pushButton_ChangeView.setMinimumSize(QSize(0, 30)) - self.pushButton_ChangeView.setFont(font1) - - self.gridLayout_2.addWidget(self.pushButton_ChangeView, 0, 2, 1, 1) - self.verticalLayout.addWidget(self.groupBox_align_position) + self.groupBox_2 = QGroupBox(self.groupBox_left) + self.groupBox_2.setObjectName(u"groupBox_2") + self.groupBox_2.setMinimumSize(QSize(0, 0)) + self.layoutWidget = QWidget(self.groupBox_2) + self.layoutWidget.setObjectName(u"layoutWidget") + self.layoutWidget.setGeometry(QRect(11, 18, 401, 41)) + self.verticalLayout_3 = QVBoxLayout(self.layoutWidget) + self.verticalLayout_3.setObjectName(u"verticalLayout_3") + self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_3 = QHBoxLayout() + self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") + self.radioButton_freqTHO = QRadioButton(self.layoutWidget) + self.radioButton_freqTHO.setObjectName(u"radioButton_freqTHO") + self.radioButton_freqTHO.setFont(font1) + + self.horizontalLayout_3.addWidget(self.radioButton_freqTHO) + + self.radioButton_freqABD = QRadioButton(self.layoutWidget) + self.radioButton_freqABD.setObjectName(u"radioButton_freqABD") + self.radioButton_freqABD.setFont(font1) + + self.horizontalLayout_3.addWidget(self.radioButton_freqABD) + + + self.verticalLayout_3.addLayout(self.horizontalLayout_3) + + + self.verticalLayout.addWidget(self.groupBox_2) + self.groupBox_view_partially = QGroupBox(self.groupBox_left) self.groupBox_view_partially.setObjectName(u"groupBox_view_partially") self.verticalLayout_2 = QVBoxLayout(self.groupBox_view_partially) @@ -456,10 +485,6 @@ class Ui_MainWindow_approximately_align(object): self.verticalLayout.addWidget(self.groupBox_view_partially) - self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) - - self.verticalLayout.addItem(self.verticalSpacer) - self.pushButton_save = QPushButton(self.groupBox_left) self.pushButton_save.setObjectName(u"pushButton_save") sizePolicy.setHeightForWidth(self.pushButton_save.sizePolicy().hasHeightForWidth()) @@ -483,11 +508,12 @@ class Ui_MainWindow_approximately_align(object): self.verticalLayout.setStretch(0, 1) self.verticalLayout.setStretch(1, 1) self.verticalLayout.setStretch(2, 3) - self.verticalLayout.setStretch(4, 2) - self.verticalLayout.setStretch(5, 4) - self.verticalLayout.setStretch(6, 1) + self.verticalLayout.setStretch(3, 4) + self.verticalLayout.setStretch(4, 3) + self.verticalLayout.setStretch(5, 2) + self.verticalLayout.setStretch(6, 4) self.verticalLayout.setStretch(7, 1) - self.verticalLayout.setStretch(8, 4) + self.verticalLayout.setStretch(8, 6) self.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1) @@ -541,13 +567,16 @@ class Ui_MainWindow_approximately_align(object): self.label_8.setText(QCoreApplication.translate("MainWindow_approximately_align", u"PSG_Post\uff1a", None)) self.pushButton_CutOff.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5e94\u7528", None)) self.groupBox_align_position.setTitle(QCoreApplication.translate("MainWindow_approximately_align", u"\u5bf9\u9f50\u8d77\u59cb\u4f4d\u7f6e", None)) - self.radioButton_PABD.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90093", None)) + self.pushButton_ChangeView.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u4f30\u8ba1\u91c7\u6837\u7387", None)) self.radioButton_NTHO.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90092", None)) - self.radioButton_custom.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u81ea\u5b9a\u4e49", None)) self.radioButton_PTHO.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90091", None)) - self.radioButton_NABD.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90094", None)) + self.radioButton_custom.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u81ea\u5b9a\u4e49", None)) + self.radioButton_PABD.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90093", None)) self.pushButton_GetPos.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u8ba1\u7b97\u5bf9\u9f50", None)) - self.pushButton_ChangeView.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5207\u6362\u89c6\u56fe", None)) + self.radioButton_NABD.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90094", None)) + self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_approximately_align", u"\u91c7\u6837\u7387\u4f30\u8ba1", None)) + self.radioButton_freqTHO.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90091", None)) + self.radioButton_freqABD.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90092", None)) self.groupBox_view_partially.setTitle(QCoreApplication.translate("MainWindow_approximately_align", u"\u5c40\u90e8\u89c2\u6d4b", None)) self.label_9.setText(QCoreApplication.translate("MainWindow_approximately_align", u"Epoch\uff1a", None)) self.pushButton_JUMP.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u8df3\u8f6c", None)) diff --git a/ui/MainWindow/MainWindow_approximately_align.ui b/ui/MainWindow/MainWindow_approximately_align.ui index daf2afc..bd9f6e9 100644 --- a/ui/MainWindow/MainWindow_approximately_align.ui +++ b/ui/MainWindow/MainWindow_approximately_align.ui @@ -25,7 +25,7 @@ 数据粗同步 - + @@ -531,15 +531,21 @@ 对齐起始位置 - - + + + + + 0 + 30 + + 12 - 备选3 + 估计采样率 @@ -555,6 +561,18 @@ + + + + + 12 + + + + 备选1 + + + @@ -567,6 +585,48 @@ + + + + + 12 + + + + 备选3 + + + + + + + + 0 + 30 + + + + + 12 + + + + 计算对齐 + + + + + + + + 12 + + + + 备选4 + + + @@ -594,69 +654,62 @@ - - - - - 12 - - - - 备选1 - - - - - - - - 12 - - - - 备选4 - - - - - - - - 0 - 30 - - - - - 12 - - - - 计算对齐 - - - - - - - - 0 - 30 - - - - - 12 - - - - 切换视图 - - - + + + + + 0 + 0 + + + + 采样率估计 + + + + + 11 + 18 + 401 + 41 + + + + + + + + + + 12 + + + + 备选1 + + + + + + + + 12 + + + + 备选2 + + + + + + + + + @@ -807,19 +860,6 @@ - - - - Qt::Orientation::Vertical - - - - 20 - 40 - - - - -- 2.43.0 From dfbc383706552eabce5eca928cc775ac5cbbd6f1 Mon Sep 17 00:00:00 2001 From: marques <20172333133@m.scnu.edu.cn> Date: Mon, 2 Jun 2025 20:27:47 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=BC=95=E7=94=A8=EF=BC=8C=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E4=BD=BF=E7=94=A8Params=E6=9B=BF=E4=BB=A3ConfigParams?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_approximately_align.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/func/Module_approximately_align.py b/func/Module_approximately_align.py index 47939a2..86a6057 100644 --- a/func/Module_approximately_align.py +++ b/func/Module_approximately_align.py @@ -1282,7 +1282,7 @@ class Data: epoch_min = response.data["epoch_min"] epoch_max = response.data["epoch_max"] - epoch_second = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"] + epoch_second = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"] temp_freq = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"] window_epoch = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["CorrByEpoch"]["window_epoch"] @@ -1326,8 +1326,8 @@ class Data: @staticmethod def estimate_frequency(bias_list): try: - epoch_second = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"] - temp_freq = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"] + epoch_second = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"] + temp_freq = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"] # 生成线性数据 X = linspace(0, len(bias_list), len(bias_list)).reshape(-1, 1) -- 2.43.0 From 364d475d1978b14b7964980feb93ff58ebd93d29 Mon Sep 17 00:00:00 2001 From: marques <20172333133@m.scnu.edu.cn> Date: Wed, 4 Jun 2025 15:35:48 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E7=B2=BE=E5=AF=B9=E9=BD=90=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=80=9A=E8=BF=87=E7=B2=97=E5=AF=B9=E9=BD=90=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=AF=B9=E5=BA=94ECG=E5=8C=BA=E9=97=B4=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98=E5=8C=96=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_approximately_align.py | 4 +- func/Module_precisely_align.py | 256 +++++++++++++++++++++++------ func/utils/Constants.py | 7 + 3 files changed, 216 insertions(+), 51 deletions(-) diff --git a/func/Module_approximately_align.py b/func/Module_approximately_align.py index 86a6057..d013997 100644 --- a/func/Module_approximately_align.py +++ b/func/Module_approximately_align.py @@ -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 = { diff --git a/func/Module_precisely_align.py b/func/Module_precisely_align.py index 98934a6..81dcdd7 100644 --- a/func/Module_precisely_align.py +++ b/func/Module_precisely_align.py @@ -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( @@ -547,12 +553,13 @@ class MainWindow_precisely_align(QMainWindow): color=Constants.PLOT_COLOR_RED, picker=True, pickradius=5, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT) self.ax2.plot(plot_element["back"]["corre"], 'o', color=Constants.PLOT_COLOR_BLUE, - markersize=3, picker=True, pickradius=5) + markersize=3, picker=True, pickradius=5) self.ax3.stem(plot_element["back"]["RRIVs"], markerfmt="b.", linefmt=Constants.PLOT_COLOR_ORANGE, 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): @@ -2051,4 +2209,4 @@ class CustomNavigationToolbar(NavigationToolbar2QT): self.cid_mouse_release = None if self.cid_mouse_hold is not None: self.canvas.mpl_disconnect(self.cid_mouse_hold) - self.cid_mouse_hold = None \ No newline at end of file + self.cid_mouse_hold = None diff --git a/func/utils/Constants.py b/func/utils/Constants.py index 2b229ad..58c564f 100644 --- a/func/utils/Constants.py +++ b/func/utils/Constants.py @@ -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 = "处理相关对齐失败" -- 2.43.0 From 65f0b9a1fa739559c81bf5c8ae3694ac30bfcadd Mon Sep 17 00:00:00 2001 From: marques <20172333133@m.scnu.edu.cn> Date: Wed, 4 Jun 2025 16:31:54 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=B8=85=E7=A9=BA=E5=B9=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0ID=E4=B8=8B=E6=8B=89=E6=A1=86=EF=BC=8C=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E9=BB=98=E8=AE=A4=E9=80=89=E4=B8=AD=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_mainwindow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/func/Module_mainwindow.py b/func/Module_mainwindow.py index 056972e..214dad5 100644 --- a/func/Module_mainwindow.py +++ b/func/Module_mainwindow.py @@ -280,7 +280,9 @@ class MainWindow(QMainWindow, Ui_Signal_Label): return sub_folders = [item.name for item in Path(path).iterdir() if item.is_dir()] + self.ui.comboBox_sampID.clear() self.ui.comboBox_sampID.addItems(sub_folders) + self.ui.comboBox_sampID.setCurrentIndex(0) def check_root_path(self): if self.ui.plainTextEdit_root_path.toPlainText() == Constants.STRING_IS_EMPTY: -- 2.43.0 From 064422fe9d164be4028dc2a1ff0efe0c7ad721c8 Mon Sep 17 00:00:00 2001 From: marques <20172333133@m.scnu.edu.cn> Date: Wed, 4 Jun 2025 16:57:14 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E7=9A=84=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF=E8=BE=93=E5=87=BA?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_precisely_align.py | 45 +++------------------------------- 1 file changed, 3 insertions(+), 42 deletions(-) diff --git a/func/Module_precisely_align.py b/func/Module_precisely_align.py index cb10bb9..e674d4b 100644 --- a/func/Module_precisely_align.py +++ b/func/Module_precisely_align.py @@ -1027,16 +1027,7 @@ 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]): @@ -1050,17 +1041,7 @@ 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"]) - 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 @@ -1386,33 +1367,13 @@ 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 -- 2.43.0 From c46916a4ef31bfe0b421a0c6bbb43a6b5b107c14 Mon Sep 17 00:00:00 2001 From: marques <20172333133@m.scnu.edu.cn> Date: Wed, 4 Jun 2025 22:26:32 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ECG=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=8C=BA=E9=97=B4=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=B8=E5=85=B3=E6=8F=90=E7=A4=BA=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_precisely_align.py | 115 +++++++++++++++++--- func/utils/Constants.py | 6 + ui/MainWindow/MainWindow_precisely_align.py | 52 ++++++++- ui/MainWindow/MainWindow_precisely_align.ui | 65 ++++++++++- 4 files changed, 216 insertions(+), 22 deletions(-) diff --git a/func/Module_precisely_align.py b/func/Module_precisely_align.py index e674d4b..8444608 100644 --- a/func/Module_precisely_align.py +++ b/func/Module_precisely_align.py @@ -9,7 +9,8 @@ from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication, QButtonGro from matplotlib import gridspec, patches from matplotlib.backends.backend_qt import NavigationToolbar2QT from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg -from numpy import (diff, where, correlate, corrcoef, sum as np_sum, max as np_max, min as np_min, arange, array, +from numpy import (diff, where, correlate, corrcoef, searchsorted, sum as np_sum, max as np_max, min as np_min, arange, + array, append, delete, abs as np_abs, argmin as np_argmin, argmax as np_argmax, asarray) from overrides import overrides from pandas import read_csv, DataFrame @@ -989,13 +990,31 @@ 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"]) + estimate_ECG_front_1 = self.data.get_corresponding_interval(Config["Coordinate"]["BCG_front_1"]).data[ + "new_point"] + estimate_ECG_front_2 = self.data.get_corresponding_interval(Config["Coordinate"]["BCG_front_2"]).data[ + "new_point"] 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"], + estimate_ECG_front_1, estimate_ECG_front_2 ), Constants.TIPS_TYPE_INFO) + if self.ui.checkBox_ECG_autoset.isChecked(): + extend_second = int(self.ui.spinBox_ECG_expend_second.value()) + + reponse = self.data.get_rriv_from_ecg_point( + estimate_ECG_front_1, extend_second, "right").data + Config["IV_Coordinate"]["ECG_front_1"] = reponse["estimate_RRIV"] + Config["Coordinate"]["ECG_front_1"] = reponse["extend_point"] + + reponse = self.data.get_rriv_from_ecg_point( + estimate_ECG_front_2, extend_second, "left").data + + Config["IV_Coordinate"]["ECG_front_2"] = reponse["estimate_RRIV"] + Config["Coordinate"]["ECG_front_2"] = reponse["extend_point"] + + 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) @@ -1008,13 +1027,30 @@ 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"]) + estimate_ECG_back_1 = self.data.get_corresponding_interval( + Config["Coordinate"]["BCG_back_1"]).data["new_point"] + estimate_ECG_back_2 = self.data.get_corresponding_interval( + Config["Coordinate"]["BCG_back_2"]).data["new_point"] 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"], + estimate_ECG_back_1, estimate_ECG_back_2 ), Constants.TIPS_TYPE_INFO) + if self.ui.checkBox_ECG_autoset.isChecked(): + extend_second = int(self.ui.spinBox_ECG_expend_second.value()) + + reponse = self.data.get_rriv_from_ecg_point( + estimate_ECG_back_1, extend_second, "right").data + Config["IV_Coordinate"]["ECG_back_1"] = reponse["estimate_RRIV"] + Config["Coordinate"]["ECG_back_1"] = reponse["extend_point"] + + reponse = self.data.get_rriv_from_ecg_point( + estimate_ECG_back_2, extend_second, "left").data + + Config["IV_Coordinate"]["ECG_back_2"] = reponse["estimate_RRIV"] + Config["Coordinate"]["ECG_back_2"] = reponse["extend_point"] + 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) @@ -1312,30 +1348,64 @@ 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]] + estimate_ECG_front_1 = self.data.get_corresponding_interval( + Config["Coordinate"]["BCG_front_1"]).data["new_point"] + estimate_ECG_front_2 = self.data.get_corresponding_interval( + Config["Coordinate"]["BCG_front_2"]).data["new_point"] 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"], + estimate_ECG_front_1, estimate_ECG_front_2 ), Constants.TIPS_TYPE_INFO) + + if self.ui.checkBox_ECG_autoset.isChecked(): + extend_second = int(self.ui.spinBox_ECG_expend_second.value()) + + reponse = self.data.get_rriv_from_ecg_point( + estimate_ECG_front_1, extend_second, "right").data + Config["IV_Coordinate"]["ECG_front_1"] = reponse["estimate_RRIV"] + Config["Coordinate"]["ECG_front_1"] = reponse["extend_point"] + + reponse = self.data.get_rriv_from_ecg_point( + estimate_ECG_front_2, extend_second, "left").data + + Config["IV_Coordinate"]["ECG_front_2"] = reponse["estimate_RRIV"] + Config["Coordinate"]["ECG_front_2"] = reponse["extend_point"] + + + 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]] + estimate_ECG_back_1 = self.data.get_corresponding_interval( + Config["Coordinate"]["BCG_back_1"]).data["new_point"] + estimate_ECG_back_2 = self.data.get_corresponding_interval( + Config["Coordinate"]["BCG_back_2"]).data["new_point"] 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"], + estimate_ECG_back_1, estimate_ECG_back_2 ), Constants.TIPS_TYPE_INFO) + + if self.ui.checkBox_ECG_autoset.isChecked(): + extend_second = int(self.ui.spinBox_ECG_expend_second.value()) + + reponse = self.data.get_rriv_from_ecg_point( + estimate_ECG_back_1, extend_second, "right").data + Config["IV_Coordinate"]["ECG_back_1"] = reponse["estimate_RRIV"] + Config["Coordinate"]["ECG_back_1"] = reponse["extend_point"] + + reponse = self.data.get_rriv_from_ecg_point( + estimate_ECG_back_2, extend_second, "left").data + + Config["IV_Coordinate"]["ECG_back_2"] = reponse["estimate_RRIV"] + Config["Coordinate"]["ECG_back_2"] = reponse["extend_point"] + elif self.ui.radioButton_ECG_front.isChecked() or self.ui.radioButton_ECG_back.isChecked(): if rect_left < 0: rect_left = 0 @@ -1374,7 +1444,6 @@ class MainWindow_precisely_align(QMainWindow): Config["Coordinate"]["ECG_back_1"] = self.data.Rpeak[:-2][indices[0]] Config["Coordinate"]["ECG_back_2"] = self.data.Rpeak[:-2][indices[-1]] - self.figToolbar.rect_start_x = None self.figToolbar.rect_end_x = None @@ -2138,6 +2207,24 @@ class Data: return Result().success(info=Constants.PRECISELY_ALIGN_GET_CORRESPONDING_INTERVAL_FINISHED, data=result) + def get_rriv_from_ecg_point(self, point:int, expend_second:int, side="left"): + extend_point = expend_second * Config["InputConfig"]["UseFreq"] + + if side == "left": + extend_point = max(point + extend_point, 0) + elif side == "right": + extend_point = min(point - extend_point, max(self.Rpeak)) + + else: + return Result().failure(info=Constants.PRECISELY_ALIGN_GET_RRIV_FROM_ECG_POINT_FAILURE + + Constants.FAILURE_REASON["Invalid_Side_Parameter"]) + + extend_estimate_RRIV = searchsorted(self.Rpeak[:-2], extend_point, side) + result = { + "estimate_RRIV": extend_estimate_RRIV, + "extend_point": extend_point + } + return Result().success(info=Constants.PRECISELY_ALIGN_GET_RRIV_FROM_ECG_POINT_FINISHED, data=result) class CustomNavigationToolbar(NavigationToolbar2QT): diff --git a/func/utils/Constants.py b/func/utils/Constants.py index 0b7f2cd..e28b358 100644 --- a/func/utils/Constants.py +++ b/func/utils/Constants.py @@ -126,6 +126,7 @@ class Constants: "Calculate_Correlation1_Exception": "(计算互相关1/2异常)", "Calculate_Correlation2_Exception": "(计算互相关2/2异常)", "Calculate_Maxvalue_Pos_Exception": "(计算最大值位置异常)", + "Invalid_Side_Parameter": "(无效的方向参数)", "Get_Epoch_Exception": "(获取epoch异常)", "Get_Corr_By_Epoch_Exception": "(通过epoch获取相关性异常)", "Predict_Exception": "(预测异常)", @@ -258,6 +259,11 @@ class Constants: PRECISELY_ALIGN_PROCESS_FINISHED: str = "处理完成" PRECISELY_ALIGN_PROCESS_FAILURE: str = "处理失败" + # + PRECISELY_ALIGN_GET_RRIV_FROM_ECG_POINT_FAILURE: str = "从ECG点获取RRIV失败" + PRECISELY_ALIGN_GET_RRIV_FROM_ECG_POINT_FINISHED: str = "从ECG点获取RRIV完成" + + PRECISELY_ALIGN_CALCULATING_CORRELATION_FRONT: str = "正在计算前段相关性" PRECISELY_ALIGN_CALCULATE_FINISHED_FRONT: str = "计算前段相关性完成" PRECISELY_ALIGN_CALCULATE_FAILURE_FRONT: str = "计算前段相关性失败" diff --git a/ui/MainWindow/MainWindow_precisely_align.py b/ui/MainWindow/MainWindow_precisely_align.py index 7a51e76..89617f2 100644 --- a/ui/MainWindow/MainWindow_precisely_align.py +++ b/ui/MainWindow/MainWindow_precisely_align.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'MainWindow_precisely_align.ui' ## -## Created by: Qt User Interface Compiler version 6.8.2 +## Created by: Qt User Interface Compiler version 6.7.0 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -16,10 +16,11 @@ from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient, QIcon, QImage, QKeySequence, QLinearGradient, QPainter, QPalette, QPixmap, QRadialGradient, QTransform) -from PySide6.QtWidgets import (QAbstractSpinBox, QApplication, QGridLayout, QGroupBox, - QHBoxLayout, QLabel, QMainWindow, QPushButton, - QRadioButton, QSizePolicy, QSpacerItem, QSpinBox, - QStatusBar, QTextBrowser, QVBoxLayout, QWidget) +from PySide6.QtWidgets import (QAbstractSpinBox, QApplication, QCheckBox, QGridLayout, + QGroupBox, QHBoxLayout, QLabel, QMainWindow, + QPushButton, QRadioButton, QSizePolicy, QSpacerItem, + QSpinBox, QStatusBar, QTextBrowser, QVBoxLayout, + QWidget) class Ui_MainWindow_precisely_align(object): def setupUi(self, MainWindow_precisely_align): @@ -96,6 +97,38 @@ class Ui_MainWindow_precisely_align(object): self.groupBox_args.setObjectName(u"groupBox_args") self.verticalLayout_5 = QVBoxLayout(self.groupBox_args) self.verticalLayout_5.setObjectName(u"verticalLayout_5") + self.groupBox_6 = QGroupBox(self.groupBox_args) + self.groupBox_6.setObjectName(u"groupBox_6") + self.horizontalLayout = QHBoxLayout(self.groupBox_6) + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.checkBox_ECG_autoset = QCheckBox(self.groupBox_6) + self.checkBox_ECG_autoset.setObjectName(u"checkBox_ECG_autoset") + self.checkBox_ECG_autoset.setChecked(True) + + self.horizontalLayout.addWidget(self.checkBox_ECG_autoset) + + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Minimum) + + self.horizontalLayout.addItem(self.horizontalSpacer) + + self.label_17 = QLabel(self.groupBox_6) + self.label_17.setObjectName(u"label_17") + self.label_17.setAlignment(Qt.AlignmentFlag.AlignRight|Qt.AlignmentFlag.AlignTrailing|Qt.AlignmentFlag.AlignVCenter) + + self.horizontalLayout.addWidget(self.label_17) + + self.spinBox_ECG_expend_second = QSpinBox(self.groupBox_6) + self.spinBox_ECG_expend_second.setObjectName(u"spinBox_ECG_expend_second") + self.spinBox_ECG_expend_second.setAlignment(Qt.AlignmentFlag.AlignRight|Qt.AlignmentFlag.AlignTrailing|Qt.AlignmentFlag.AlignVCenter) + self.spinBox_ECG_expend_second.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons) + self.spinBox_ECG_expend_second.setMaximum(1000000) + self.spinBox_ECG_expend_second.setValue(30) + + self.horizontalLayout.addWidget(self.spinBox_ECG_expend_second) + + + self.verticalLayout_5.addWidget(self.groupBox_6) + self.groupBox_2 = QGroupBox(self.groupBox_args) self.groupBox_2.setObjectName(u"groupBox_2") self.verticalLayout_2 = QVBoxLayout(self.groupBox_2) @@ -426,6 +459,11 @@ class Ui_MainWindow_precisely_align(object): self.verticalLayout_5.addWidget(self.groupBox_5) + self.verticalLayout_5.setStretch(0, 2) + self.verticalLayout_5.setStretch(1, 2) + self.verticalLayout_5.setStretch(2, 2) + self.verticalLayout_5.setStretch(3, 2) + self.verticalLayout_5.setStretch(4, 2) self.verticalLayout.addWidget(self.groupBox_args) @@ -489,7 +527,6 @@ class Ui_MainWindow_precisely_align(object): self.verticalLayout.setStretch(0, 1) self.verticalLayout.setStretch(1, 7) - self.verticalLayout.setStretch(2, 2) self.verticalLayout.setStretch(3, 1) self.verticalLayout.setStretch(4, 1) self.verticalLayout.setStretch(5, 5) @@ -517,6 +554,9 @@ class Ui_MainWindow_precisely_align(object): self.pushButton_input_setting.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u5bfc\u5165\u8bbe\u7f6e", None)) self.pushButton_input.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u5f00\u59cb\u5bfc\u5165", None)) self.groupBox_args.setTitle(QCoreApplication.translate("MainWindow_precisely_align", u"\u53c2\u6570\u8f93\u5165", None)) + self.groupBox_6.setTitle(QCoreApplication.translate("MainWindow_precisely_align", u"ECG\u81ea\u52a8\u83b7\u53d6\u533a\u95f4", None)) + self.checkBox_ECG_autoset.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u81ea\u52a8\u83b7\u53d6ECG\u533a\u95f4", None)) + self.label_17.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u62d3\u5c55\u79d2\u6570\uff1a", None)) self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_precisely_align", u"\u524d\u6bb5BCG\u533a\u95f4\u5750\u6807\u53d6\u503c", None)) self.radioButton_BCG_front.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u524d\u6bb5BCG", None)) self.label_4.setText(QCoreApplication.translate("MainWindow_precisely_align", u"~", None)) diff --git a/ui/MainWindow/MainWindow_precisely_align.ui b/ui/MainWindow/MainWindow_precisely_align.ui index 566269e..f4e7095 100644 --- a/ui/MainWindow/MainWindow_precisely_align.ui +++ b/ui/MainWindow/MainWindow_precisely_align.ui @@ -56,7 +56,7 @@ 数据精同步 - + @@ -102,7 +102,68 @@ 参数输入 - + + + + + ECG自动获取区间 + + + + + + 自动获取ECG区间 + + + true + + + + + + + Qt::Orientation::Horizontal + + + QSizePolicy::Policy::Preferred + + + + 40 + 20 + + + + + + + + 拓展秒数: + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + + + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + QAbstractSpinBox::ButtonSymbols::NoButtons + + + 1000000 + + + 30 + + + + + + -- 2.43.0