From 953136c9c5466a46861d466c16ad6d7f94dfb7a4 Mon Sep 17 00:00:00 2001 From: Yorusora <2023025086@m.scnu.edu.cn> Date: Tue, 10 Jun 2025 12:07:11 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=B0=86<=E4=BA=BA=E5=B7=A5=E7=BA=A0?= =?UTF-8?q?=E6=AD=A3>=E5=92=8C<=E5=91=BC=E5=90=B8=E5=8F=AF=E7=94=A8?= =?UTF-8?q?=E6=80=A7=E5=8F=8A=E9=97=B4=E6=9C=9F=E6=A0=87=E6=B3=A8>?= =?UTF-8?q?=E7=9A=84=E5=B7=A6=E9=94=AE=E5=AF=BB=E5=B3=B0=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=B3=B0=E5=80=BC=E4=BF=AE=E6=94=B9=E4=B8=BA=E4=BA=86=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E6=9C=89=E4=B8=8A=E9=99=90=E4=B8=8B=E9=99=90=E7=9A=84?= =?UTF-8?q?=E7=9F=A9=E5=BD=A2=E6=9D=A5=E8=8E=B7=E5=8F=96=E5=B3=B0=E5=80=BC?= =?UTF-8?q?=E5=9D=90=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- func/Module_label_check.py | 53 ++++++++++++++++++++++++++----- func/Module_resp_quality_label.py | 47 +++++++++++++++++++++++---- 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 5fc67c3..2fac0b4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ 每个功能运行时,若./Config目录下不存在该功能对应的yaml配置文件,则程序将创建一份默认的配置文件。配置文件的内容主要涉及一些对应功能的界面默认初始值的设置,此配置文件可以根据用户需要自行修改,或是在修改了相应参数后,在导入设置界面中单击“确定”即可保存相关参数到yaml文件中。 ## TODO LIST: -1、根据选定区域获取峰值时,将绘制的区域设置为有上限和下限的矩形,根据矩形获取到的横纵区域来计算峰值 +~~1、根据选定区域获取峰值时,将绘制的区域设置为有上限和下限的矩形,根据矩形获取到的横纵区域来计算峰值~~ ~~2、体动选取区域的判别尚未做的很完整,选中多个已有的体动的区域时可能会出现问题~~ diff --git a/func/Module_label_check.py b/func/Module_label_check.py index 8273a56..6d2a920 100644 --- a/func/Module_label_check.py +++ b/func/Module_label_check.py @@ -758,6 +758,7 @@ class MainWindow_label_check(QMainWindow): elif event.button == 3: self.is_right_button_pressed = True self.figToolbar.rect_start_x = event.xdata + self.figToolbar.rect_start_y = event.ydata # 如果矩形patch已存在,先移除 if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None: self.figToolbar.rect_patch_ax0.remove() @@ -768,9 +769,11 @@ class MainWindow_label_check(QMainWindow): def on_release(self, event): if self.figToolbar.action_Label_Multiple.isChecked(): - if self.figToolbar.rect_start_x is not None: + if self.figToolbar.rect_start_x is not None and self.figToolbar.rect_start_y is not None: self.figToolbar.rect_end_x = event.xdata - if self.figToolbar.rect_start_x is not None and self.figToolbar.rect_end_x is not None: + self.figToolbar.rect_end_y = event.ydata + if ((self.figToolbar.rect_start_x is not None and self.figToolbar.rect_end_x is not None) and + (self.figToolbar.rect_start_y is not None and self.figToolbar.rect_end_y is not None)): if self.figToolbar.rect_start_x < self.figToolbar.rect_end_x: rect_left = self.figToolbar.rect_start_x rect_right = self.figToolbar.rect_end_x @@ -780,9 +783,20 @@ class MainWindow_label_check(QMainWindow): else: rect_left = self.figToolbar.rect_start_x rect_right = self.figToolbar.rect_start_x + if self.figToolbar.rect_start_y < self.figToolbar.rect_end_y: + rect_bottom = self.figToolbar.rect_start_y + rect_top = self.figToolbar.rect_end_y + elif self.figToolbar.rect_start_y > self.figToolbar.rect_end_y: + rect_bottom = self.figToolbar.rect_end_y + rect_top = self.figToolbar.rect_start_y + else: + rect_bottom = self.figToolbar.rect_start_y + rect_top = self.figToolbar.rect_start_y else: rect_left = self.figToolbar.rect_start_x rect_right = self.figToolbar.rect_start_x + rect_bottom = self.figToolbar.rect_start_y + rect_top = self.figToolbar.rect_start_y if event.button == 1 and self.is_left_button_pressed: self.is_left_button_pressed = False if rect_left < 0: @@ -796,6 +810,13 @@ class MainWindow_label_check(QMainWindow): rect_left = 0 rect_right = 0 selected_area_for_add_points = self.data.processed_data[int(rect_left):int(rect_right)] + # 找到子列表的最小值 + min_value = min(selected_area_for_add_points) + # 遍历子列表,将不满足条件的元素替换为最小值 + selected_area_for_add_points = [ + y if rect_bottom < y < rect_top else min_value + for y in selected_area_for_add_points + ] peaks_idx, _ = find_peaks(selected_area_for_add_points, height=Config["FindPeaks"]["MinHeight"], distance=Config["FindPeaks"]["MinInterval"]) @@ -827,6 +848,8 @@ class MainWindow_label_check(QMainWindow): self.__redraw_peaks__() self.figToolbar.rect_start_x = None self.figToolbar.rect_end_x = None + self.figToolbar.rect_start_y = None + self.figToolbar.rect_end_y = None self.data.corrected_peak.sort() self.data.corrected_peak_y = [self.data.processed_data[x] for x in self.data.corrected_peak] self.__update_tableWidget_and_info__() @@ -850,6 +873,8 @@ class MainWindow_label_check(QMainWindow): def on_hold(self, event): if self.figToolbar.rect_start_x is not None and event.xdata is not None: self.figToolbar.rect_end_x = event.xdata + if self.figToolbar.rect_start_y is not None and event.ydata is not None: + self.figToolbar.rect_end_y = event.ydata # 如果矩形patch不存在,则创建一个新的 if self.figToolbar.rect_patch_ax0 is None: @@ -878,14 +903,24 @@ class MainWindow_label_check(QMainWindow): # 更新矩形patch的位置和大小 x_start = self.figToolbar.rect_start_x x_end = self.figToolbar.rect_end_x - rect_down = min(self.ax0.get_ylim()[0], self.ax1.get_ylim()[0]) - 1000 - rect_up = max(self.ax0.get_ylim()[1], self.ax1.get_ylim()[1]) + 1000 - self.figToolbar.rect_patch_ax0.set_xy((min(x_start, x_end), rect_down)) + + if self.is_left_button_pressed: + y_start = self.figToolbar.rect_start_y + y_end = self.figToolbar.rect_end_y + self.figToolbar.rect_patch_ax0.set_xy((min(x_start, x_end), min(y_start, y_end))) + self.figToolbar.rect_patch_ax0.set_height(abs(y_end - y_start)) + self.figToolbar.rect_patch_ax1.set_xy((min(x_start, x_end), min(y_start, y_end))) + self.figToolbar.rect_patch_ax1.set_height(abs(y_end - y_start)) + elif self.is_right_button_pressed: + y_start = min(self.ax0.get_ylim()[0], self.ax1.get_ylim()[0]) - 1000 + y_end = max(self.ax0.get_ylim()[1], self.ax1.get_ylim()[1]) + 1000 + self.figToolbar.rect_patch_ax0.set_xy((min(x_start, x_end), y_start)) + self.figToolbar.rect_patch_ax0.set_height(abs(y_end - y_start)) + self.figToolbar.rect_patch_ax1.set_xy((min(x_start, x_end), y_start)) + self.figToolbar.rect_patch_ax1.set_height(abs(y_end - y_start)) + self.figToolbar.rect_patch_ax0.set_width(abs(x_end - x_start)) - self.figToolbar.rect_patch_ax0.set_height(rect_up - rect_down) - self.figToolbar.rect_patch_ax1.set_xy((min(x_start, x_end), rect_down)) self.figToolbar.rect_patch_ax1.set_width(abs(x_end - x_start)) - self.figToolbar.rect_patch_ax1.set_height(rect_up - rect_down) self.canvas.draw() @@ -1071,6 +1106,8 @@ class CustomNavigationToolbar(NavigationToolbar2QT): # 初始化矩形选择区域 self.rect_start_x = None self.rect_end_x = None + self.rect_start_y = None + self.rect_end_y = None self.rect_patch_ax0 = None # 用于绘制矩形的patch self.rect_patch_ax1 = None # 用于绘制矩形的patch diff --git a/func/Module_resp_quality_label.py b/func/Module_resp_quality_label.py index 88a62ba..bcf9c8f 100644 --- a/func/Module_resp_quality_label.py +++ b/func/Module_resp_quality_label.py @@ -1166,6 +1166,7 @@ class MainWindow_resp_quality_label(QMainWindow): elif event.button == 3: self.is_right_button_pressed = True self.figToolbar.rect_start_x = event.xdata + self.figToolbar.rect_start_y = event.ydata # 如果矩形patch已存在,先移除 if self.figToolbar.rect_patch_ax1 is not None: self.figToolbar.rect_patch_ax1.remove() @@ -1174,9 +1175,11 @@ class MainWindow_resp_quality_label(QMainWindow): def on_release(self, event): if self.figToolbar.action_Label_Multiple.isChecked(): - if self.figToolbar.rect_start_x is not None: + if self.figToolbar.rect_start_x is not None and self.figToolbar.rect_start_y is not None: self.figToolbar.rect_end_x = event.xdata - if self.figToolbar.rect_start_x is not None and self.figToolbar.rect_end_x is not None: + self.figToolbar.rect_end_y = event.ydata + if ((self.figToolbar.rect_start_x is not None and self.figToolbar.rect_end_x is not None) and + (self.figToolbar.rect_start_y is not None and self.figToolbar.rect_end_y is not None)): if self.figToolbar.rect_start_x < self.figToolbar.rect_end_x: rect_left = self.figToolbar.rect_start_x rect_right = self.figToolbar.rect_end_x @@ -1186,9 +1189,20 @@ class MainWindow_resp_quality_label(QMainWindow): else: rect_left = self.figToolbar.rect_start_x rect_right = self.figToolbar.rect_start_x + if self.figToolbar.rect_start_y < self.figToolbar.rect_end_y: + rect_bottom = self.figToolbar.rect_start_y + rect_top = self.figToolbar.rect_end_y + elif self.figToolbar.rect_start_y > self.figToolbar.rect_end_y: + rect_bottom = self.figToolbar.rect_end_y + rect_top = self.figToolbar.rect_start_y + else: + rect_bottom = self.figToolbar.rect_start_y + rect_top = self.figToolbar.rect_start_y else: rect_left = self.figToolbar.rect_start_x rect_right = self.figToolbar.rect_start_x + rect_bottom = self.figToolbar.rect_start_y + rect_top = self.figToolbar.rect_start_y if event.button == 1 and self.is_left_button_pressed: self.is_left_button_pressed = False if rect_left < Config["CurrentThoIndex"]: @@ -1205,6 +1219,13 @@ class MainWindow_resp_quality_label(QMainWindow): rect_left = 0 rect_right = 0 selected_area_for_add_points = self.data.Tho_Processed[int(rect_left):int(rect_right)] + # 找到子列表的最小值 + min_value = min(selected_area_for_add_points) + # 遍历子列表,将不满足条件的元素替换为最小值 + selected_area_for_add_points = [ + y if rect_bottom < y < rect_top else min_value + for y in selected_area_for_add_points + ] peaks_idx, _ = find_peaks(selected_area_for_add_points, height=float(Config["FindPeaks"]["MinHeight"]), distance=float(Config["FindPeaks"]["MinInterval"])) @@ -1243,6 +1264,8 @@ class MainWindow_resp_quality_label(QMainWindow): self.data.Tho_peak_y = [self.data.Tho_Processed[x] for x in self.data.Tho_peak] self.figToolbar.rect_start_x = None self.figToolbar.rect_end_x = None + self.figToolbar.rect_start_y = None + self.figToolbar.rect_end_y = None result = self.data.save_tho_peak() if not result.status: @@ -1262,6 +1285,8 @@ class MainWindow_resp_quality_label(QMainWindow): def on_hold(self, event): if self.figToolbar.rect_start_x is not None and event.xdata is not None: self.figToolbar.rect_end_x = event.xdata + if self.figToolbar.rect_start_y is not None and event.ydata is not None: + self.figToolbar.rect_end_y = event.ydata # 如果矩形patch不存在,则创建一个新的 if self.figToolbar.rect_patch_ax1 is None: @@ -1278,11 +1303,19 @@ class MainWindow_resp_quality_label(QMainWindow): # 更新矩形patch的位置和大小 x_start = self.figToolbar.rect_start_x x_end = self.figToolbar.rect_end_x - rect_down = self.ax1.get_ylim()[0] - 1000 - rect_up = self.ax1.get_ylim()[1] + 1000 - self.figToolbar.rect_patch_ax1.set_xy((min(x_start, x_end), rect_down)) + + if self.is_left_button_pressed: + y_start = self.figToolbar.rect_start_y + y_end = self.figToolbar.rect_end_y + self.figToolbar.rect_patch_ax1.set_xy((min(x_start, x_end), min(y_start, y_end))) + self.figToolbar.rect_patch_ax1.set_height(abs(y_end - y_start)) + elif self.is_right_button_pressed: + y_start = min(self.ax0.get_ylim()[0], self.ax1.get_ylim()[0]) - 1000 + y_end = max(self.ax0.get_ylim()[1], self.ax1.get_ylim()[1]) + 1000 + self.figToolbar.rect_patch_ax1.set_xy((min(x_start, x_end), y_start)) + self.figToolbar.rect_patch_ax1.set_height(abs(y_end - y_start)) + self.figToolbar.rect_patch_ax1.set_width(abs(x_end - x_start)) - self.figToolbar.rect_patch_ax1.set_height(rect_up - rect_down) self.canvas.draw() @@ -1603,6 +1636,8 @@ class CustomNavigationToolbar(NavigationToolbar2QT): # 初始化矩形选择区域 self.rect_start_x = None self.rect_end_x = None + self.rect_start_y = None + self.rect_end_y = None self.rect_patch_ax1 = None # 用于绘制矩形的patch def home(self, *args): From 32ceb1471fbebc9fc756f8e34858318bc1b036e1 Mon Sep 17 00:00:00 2001 From: Yorusora <2023025086@m.scnu.edu.cn> Date: Tue, 10 Jun 2025 13:35:50 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E7=82=B9=E5=87=BB=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=97=B6=EF=BC=8C=E7=A8=8B=E5=BA=8F=E5=B0=86?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=A3=80=E6=9F=A5=E5=B9=B6=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=96=87=E4=BB=B6=E7=9A=84=E9=87=87=E6=A0=B7?= =?UTF-8?q?=E7=8E=87=EF=BC=8C=E8=8B=A5=E8=83=BD=E8=8E=B7=E5=8F=96=E6=88=90?= =?UTF-8?q?=E5=8A=9F=EF=BC=8C=E5=88=99=E5=B0=86=E6=95=B0=E5=80=BC=E5=A1=AB?= =?UTF-8?q?=E5=85=A5=E5=AF=BC=E5=85=A5=E8=AE=BE=E7=BD=AE=E7=9A=84=E9=87=87?= =?UTF-8?q?=E6=A0=B7=E7=8E=87=E4=B8=AD=E3=80=82=E8=8B=A5=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=EF=BC=8C=E5=88=99=E5=BC=B9=E7=AA=97=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E5=B9=B6=E5=A1=AB=E5=85=A5yaml=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=AD=E7=9A=84=E9=A2=84=E8=AE=BE=E9=87=87?= =?UTF-8?q?=E6=A0=B7=E7=8E=87=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_SA_label.py | 57 ++++++++++++++++++++++++++++++ func/Module_approximately_align.py | 33 +++++++++++++++++ func/Module_artifact_label.py | 25 +++++++++++++ func/Module_bcg_quality_label.py | 19 +++++++++- func/Module_detect_Jpeak.py | 17 +++++++++ func/Module_detect_Rpeak.py | 18 ++++++++++ func/Module_label_check.py | 23 ++++++++++++ func/Module_precisely_align.py | 39 ++++++++++++++++++++ func/Module_preprocess.py | 24 +++++++++++++ func/Module_resp_quality_label.py | 25 +++++++++++++ func/utils/Constants.py | 1 + 11 files changed, 280 insertions(+), 1 deletion(-) diff --git a/func/Module_SA_label.py b/func/Module_SA_label.py index e515076..5b03bec 100644 --- a/func/Module_SA_label.py +++ b/func/Module_SA_label.py @@ -87,8 +87,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq_signal_OrgBCG.valueChanged.connect(self.__update_ui__) self.ui.spinBox_input_freq_signal_Tho.valueChanged.connect(self.__update_ui__) @@ -237,6 +241,59 @@ class SettingWindow(QMainWindow): str(self.ui.spinBox_input_freq_signal_SpO2.value()) + Params.ENDSWITH_TXT)))) + def __examine_freq__(self): + if Path(Config["Path"]["Input_OrgBCG"]).is_file(): + Config["Path"]["Input_OrgBCG"] = str(Path(Config["Path"]["Input_OrgBCG"]).parent) + if Path(Config["Path"]["Input_Tho"]).is_file(): + Config["Path"]["Input_Tho"] = str(Path(Config["Path"]["Input_Tho"]).parent) + if Path(Config["Path"]["Input_Abd"]).is_file(): + Config["Path"]["Input_Abd"] = str(Path(Config["Path"]["Input_Abd"]).parent) + if Path(Config["Path"]["Input_FlowT"]).is_file(): + Config["Path"]["Input_FlowT"] = str(Path(Config["Path"]["Input_FlowT"]).parent) + if Path(Config["Path"]["Input_FlowP"]).is_file(): + Config["Path"]["Input_FlowP"] = str(Path(Config["Path"]["Input_FlowP"]).parent) + if Path(Config["Path"]["Input_SpO2"]).is_file(): + Config["Path"]["Input_SpO2"] = str(Path(Config["Path"]["Input_SpO2"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ORGBCG_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["ThoFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.THO_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], Filename.ABD_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["AbdFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ABD_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_FlowT"], Filename.FLOWT_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["FlowTFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.FLOWT_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_FlowP"], Filename.FLOWP_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["FlowPFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.FLOWP_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_SpO2"], Filename.SPO2_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["SpO2Freq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.SPO2_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq_signal_OrgBCG.setValue(Config["InputConfig"]["OrgBCGFreq"]) + self.ui.spinBox_input_freq_signal_Tho.setValue(Config["InputConfig"]["ThoFreq"]) + self.ui.spinBox_input_freq_signal_Abd.setValue(Config["InputConfig"]["AbdFreq"]) + self.ui.spinBox_input_freq_signal_FlowT.setValue(Config["InputConfig"]["FlowTFreq"]) + self.ui.spinBox_input_freq_signal_FlowP.setValue(Config["InputConfig"]["FlowPFreq"]) + self.ui.spinBox_input_freq_signal_SpO2.setValue(Config["InputConfig"]["SpO2Freq"]) + class MainWindow_SA_label(QMainWindow): diff --git a/func/Module_approximately_align.py b/func/Module_approximately_align.py index 7cd93c0..0ef13bc 100644 --- a/func/Module_approximately_align.py +++ b/func/Module_approximately_align.py @@ -86,8 +86,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_orgBcg_freq.valueChanged.connect(self.__update_ui__) self.ui.spinBox_input_Tho_freq.valueChanged.connect(self.__update_ui__) @@ -195,6 +199,35 @@ class SettingWindow(QMainWindow): str(self.ui.spinBox_input_Abd_freq.value()) + Params.ENDSWITH_TXT)))) + def __examine_freq__(self): + if Path(Config["Path"]["Input_orgBcg"]).is_file(): + Config["Path"]["Input_orgBcg"] = str(Path(Config["Path"]["Input_orgBcg"]).parent) + if Path(Config["Path"]["Input_Tho"]).is_file(): + Config["Path"]["Input_Tho"] = str(Path(Config["Path"]["Input_Tho"]).parent) + if Path(Config["Path"]["Input_Abd"]).is_file(): + Config["Path"]["Input_Abd"] = str(Path(Config["Path"]["Input_Abd"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_RAW, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["orgBcgFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ORGBCG_RAW + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_RAW, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["ThoFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.THO_RAW + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], Filename.ABD_RAW, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["AbdFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ABD_RAW + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_orgBcg_freq.setValue(Config["InputConfig"]["orgBcgFreq"]) + self.ui.spinBox_input_Tho_freq.setValue(Config["InputConfig"]["ThoFreq"]) + self.ui.spinBox_input_Abd_freq.setValue(Config["InputConfig"]["AbdFreq"]) + class MainWindow_approximately_align(QMainWindow): diff --git a/func/Module_artifact_label.py b/func/Module_artifact_label.py index 3a5b63a..684106a 100644 --- a/func/Module_artifact_label.py +++ b/func/Module_artifact_label.py @@ -71,8 +71,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq_orgBcg.valueChanged.connect(self.__update_ui__) self.ui.spinBox_input_freq_BCG.valueChanged.connect(self.__update_ui__) @@ -152,6 +156,27 @@ class SettingWindow(QMainWindow): str(self.ui.spinBox_input_freq_BCG.value()) + Params.ENDSWITH_TXT)))) + def __examine_freq__(self): + if Path(Config["Path"]["Input_orgBcg"]).is_file(): + Config["Path"]["Input_orgBcg"] = str(Path(Config["Path"]["Input_orgBcg"]).parent) + if Path(Config["Path"]["Input_BCG"]).is_file(): + Config["Path"]["Input_BCG"] = str(Path(Config["Path"]["Input_BCG"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["orgBcgFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ORGBCG_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["BCGFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.BCG_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq_orgBcg.setValue(Config["InputConfig"]["orgBcgFreq"]) + self.ui.spinBox_input_freq_BCG.setValue(Config["InputConfig"]["BCGFreq"]) + class MainWindow_artifact_label(QMainWindow): diff --git a/func/Module_bcg_quality_label.py b/func/Module_bcg_quality_label.py index 7d9b37b..50a2958 100644 --- a/func/Module_bcg_quality_label.py +++ b/func/Module_bcg_quality_label.py @@ -73,8 +73,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq_signal_BCG.valueChanged.connect(self.__update_ui__) self.ui.radioButton_30s_mode.clicked.connect(self.__update_mode__) @@ -149,6 +153,19 @@ class SettingWindow(QMainWindow): elif self.ui.radioButton_10s_mode.isChecked(): Config["Mode"] = "10s" + def __examine_freq__(self): + if Path(Config["Path"]["Input_BCG"]).is_file(): + Config["Path"]["Input_BCG"] = str(Path(Config["Path"]["Input_BCG"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["BCGFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.BCG_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq_signal_BCG.setValue(Config["InputConfig"]["BCGFreq"]) + class MainWindow_bcg_quality_label(QMainWindow): @@ -990,7 +1007,7 @@ class Data(): result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_SYNC, Params.ENDSWITH_TXT) if result.status: Config["Path"]["Input_BCG"] = result.data["path"] - Config["InputConfig"]["ThoFreq"] = result.data["freq"] + Config["InputConfig"]["BCGFreq"] = result.data["freq"] else: return result diff --git a/func/Module_detect_Jpeak.py b/func/Module_detect_Jpeak.py index 120fb8f..cea128c 100644 --- a/func/Module_detect_Jpeak.py +++ b/func/Module_detect_Jpeak.py @@ -51,8 +51,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq.valueChanged.connect(self.__update_ui__) self.ui.pushButton_confirm.clicked.connect(self.__write_config__) @@ -112,6 +116,19 @@ class SettingWindow(QMainWindow): str(self.ui.spinBox_input_freq.value()) + Params.ENDSWITH_TXT)))) + def __examine_freq__(self): + if Path(Config["Path"]["Input"]).is_file(): + Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input"], Filename.BCG_FILTER, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["Freq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.BCG_FILTER + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq.setValue(Config["InputConfig"]["Freq"]) + class MainWindow_detect_Jpeak(QMainWindow): diff --git a/func/Module_detect_Rpeak.py b/func/Module_detect_Rpeak.py index deed19c..4e9b91f 100644 --- a/func/Module_detect_Rpeak.py +++ b/func/Module_detect_Rpeak.py @@ -51,8 +51,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq.valueChanged.connect(self.__update_ui__) self.ui.pushButton_confirm.clicked.connect(self.__write_config__) @@ -109,6 +113,20 @@ class SettingWindow(QMainWindow): str(self.ui.spinBox_input_freq.value()) + Params.ENDSWITH_TXT)))) + def __examine_freq__(self): + if Path(Config["Path"]["Input"]).is_file(): + Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input"], Filename.ECG_FILTER, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["Freq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ECG_FILTER + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], + Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq.setValue(Config["InputConfig"]["Freq"]) + class MainWindow_detect_Rpeak(QMainWindow): diff --git a/func/Module_label_check.py b/func/Module_label_check.py index 6d2a920..1670e47 100644 --- a/func/Module_label_check.py +++ b/func/Module_label_check.py @@ -60,8 +60,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq_signal.valueChanged.connect(self.__update_ui__) self.ui.spinBox_bandPassOrder.valueChanged.connect(self.__update_ui__) @@ -192,6 +196,25 @@ class SettingWindow(QMainWindow): else: raise ValueError("模式不存在") + def __examine_freq__(self): + if Config["Mode"] == "BCG": + signal = Filename.BCG_FILTER + elif Config["Mode"] == "ECG": + signal = Filename.ECG_FILTER + else: + raise ValueError("模式不存在") + if Path(Config["Path"]["Input_Signal"]).is_file(): + Config["Path"]["Input_Signal"] = str(Path(Config["Path"]["Input_Signal"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input_Signal"], signal, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["Freq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, signal + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq_signal.setValue(Config["InputConfig"]["Freq"]) + class MainWindow_label_check(QMainWindow): diff --git a/func/Module_precisely_align.py b/func/Module_precisely_align.py index 582a83e..1d7c043 100644 --- a/func/Module_precisely_align.py +++ b/func/Module_precisely_align.py @@ -92,8 +92,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq_orgBcg.valueChanged.connect(self.__update_ui__) self.ui.spinBox_input_freq_BCG.valueChanged.connect(self.__update_ui__) @@ -255,6 +259,41 @@ class SettingWindow(QMainWindow): str(self.ui.spinBox_input_freq_ECG.value()) + Params.ENDSWITH_TXT)))) + def __examine_freq__(self): + if Path(Config["Path"]["Input_OrgBCG"]).is_file(): + Config["Path"]["Input_OrgBCG"] = str(Path(Config["Path"]["Input_OrgBCG"]).parent) + if Path(Config["Path"]["Input_BCG"]).is_file(): + Config["Path"]["Input_BCG"] = str(Path(Config["Path"]["Input_BCG"]).parent) + if Path(Config["Path"]["Input_Jpeak"]).is_file(): + Config["Path"]["Input_Jpeak"] = str(Path(Config["Path"]["Input_Jpeak"]).parent) + if Path(Config["Path"]["Input_ECG"]).is_file(): + Config["Path"]["Input_ECG"] = str(Path(Config["Path"]["Input_ECG"]).parent) + if Path(Config["Path"]["Input_Rpeak"]).is_file(): + Config["Path"]["Input_Rpeak"] = str(Path(Config["Path"]["Input_Rpeak"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_RAW, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["orgBcgFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ORGBCG_RAW + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_FILTER, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["BCGFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.BCG_FILTER + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], Filename.ECG_FILTER, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["ECGFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ECG_FILTER + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq_orgBcg.setValue(Config["InputConfig"]["orgBcgFreq"]) + self.ui.spinBox_input_freq_BCG.setValue(Config["InputConfig"]["BCGFreq"]) + self.ui.spinBox_input_freq_ECG.setValue(Config["InputConfig"]["ECGFreq"]) + class MainWindow_precisely_align(QMainWindow): diff --git a/func/Module_preprocess.py b/func/Module_preprocess.py index 4cd679e..c22d4ab 100644 --- a/func/Module_preprocess.py +++ b/func/Module_preprocess.py @@ -53,8 +53,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq.valueChanged.connect(self.__update_ui__) self.ui.spinBox_output_freq.valueChanged.connect(self.__update_ui__) @@ -140,6 +144,26 @@ class SettingWindow(QMainWindow): else: raise ValueError("模式不存在") + def __examine_freq__(self): + if Config["Mode"] == "BCG": + signal = Filename.ORGBCG_RAW + elif Config["Mode"] == "ECG": + signal = Filename.ECG_RAW + else: + raise ValueError("模式不存在") + + if Path(Config["Path"]["Input"]).is_file(): + Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input"], signal, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["Freq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, signal + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq.setValue(Config["InputConfig"]["Freq"]) + class MainWindow_preprocess(QMainWindow): diff --git a/func/Module_resp_quality_label.py b/func/Module_resp_quality_label.py index bcf9c8f..b37018c 100644 --- a/func/Module_resp_quality_label.py +++ b/func/Module_resp_quality_label.py @@ -74,8 +74,12 @@ class SettingWindow(QMainWindow): self.root_path = root_path self.sampID = sampID + self.msgBox = QMessageBox() + self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE) + self.config = None self.__read_config__() + self.__examine_freq__() self.ui.spinBox_input_freq_signal_OrgBCG.valueChanged.connect(self.__update_ui__) self.ui.spinBox_input_freq_signal_Tho.valueChanged.connect(self.__update_ui__) @@ -159,6 +163,27 @@ class SettingWindow(QMainWindow): str(self.ui.spinBox_input_freq_signal_Tho.value()) + Params.ENDSWITH_TXT)))) + def __examine_freq__(self): + if Path(Config["Path"]["Input_OrgBCG"]).is_file(): + Config["Path"]["Input_OrgBCG"] = str(Path(Config["Path"]["Input_OrgBCG"]).parent) + if Path(Config["Path"]["Input_Tho"]).is_file(): + Config["Path"]["Input_Tho"] = str(Path(Config["Path"]["Input_Tho"]).parent) + + result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.ORGBCG_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_SYNC, Params.ENDSWITH_TXT) + if result.status: + Config["InputConfig"]["ThoFreq"] = result.data["freq"] + else: + PublicFunc.msgbox_output(self, Filename.THO_SYNC + Constants.FAILURE_REASON["Get_Freq_Not_Correct"], Constants.MSGBOX_TYPE_ERROR) + + # 数据回显 + self.ui.spinBox_input_freq_signal_OrgBCG.setValue(Config["InputConfig"]["OrgBCGFreq"]) + self.ui.spinBox_input_freq_signal_Tho.setValue(Config["InputConfig"]["ThoFreq"]) + class MainWindow_resp_quality_label(QMainWindow): diff --git a/func/utils/Constants.py b/func/utils/Constants.py index bbc2c04..a6f5371 100644 --- a/func/utils/Constants.py +++ b/func/utils/Constants.py @@ -114,6 +114,7 @@ class Constants: "Save_File_Not_Found": "(保存路径不存在)", "OrgBCG_Cut_Length_Not_Correct": "(OrgBCG的切割长度不正确,Pre+Post长度大于信号长度)", "PSG_Cut_Length_Not_Correct": "(PSG的切割长度不正确,Pre+Post长度大于信号长度)", + "Get_Freq_Not_Correct": "(无法获取数据采样率,将填入配置文件中的采样率。可能是因为文件不存在或文件命名格式不正确导致,请检查数据)", "Open_Data_Exception": "(打开数据异常)", "Process_Exception": "(处理异常)", From 1a0284db16c11351b461729e57df87061e21facb Mon Sep 17 00:00:00 2001 From: Yorusora <2023025086@m.scnu.edu.cn> Date: Tue, 10 Jun 2025 13:37:26 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2fac0b4..9f21b2b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ~~2、体动选取区域的判别尚未做的很完整,选中多个已有的体动的区域时可能会出现问题~~ -3、部分模块在导入失败后重新导入时会出现问题,已知模块有<人工纠正>、<体动标注>、<呼吸可用性及间期标注>、<睡眠呼吸暂停事件标注>,主要是涉及到按钮状态的设置,有待后续优化。当前将这些有涉及到的功能,禁止了导入数据后在不关闭界面的情况下直接重新导入 +~~3、部分模块在导入失败后重新导入时会出现问题,已知模块有<人工纠正>、<体动标注>、<呼吸可用性及间期标注>、<睡眠呼吸暂停事件标注>,主要是涉及到按钮状态的设置,有待后续优化。当前将这些有涉及到的功能,禁止了导入数据后在不关闭界面的情况下直接重新导入~~ 4、在J峰算法定位的时候滤波导致的信号偏移,导致之后的峰值坐标点与实际峰值出现偏移 @@ -21,7 +21,7 @@ ~~7、各个模块中的检测父级文件夹是否存在的功能仍存在问题,无法正确创建文件夹~~ -8、将导入设置中的采样率修改为自动获取数据文件名中的采样率 +~~8、将导入设置中的采样率修改为自动获取数据文件名中的采样率~~ ## 1、主菜单 From bbd043cf58dd3df86381e17be0fe185b69cc194f Mon Sep 17 00:00:00 2001 From: Yorusora <2023025086@m.scnu.edu.cn> Date: Tue, 10 Jun 2025 13:46:33 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- func/Module_approximately_align.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/func/Module_approximately_align.py b/func/Module_approximately_align.py index 0ef13bc..902dcc3 100644 --- a/func/Module_approximately_align.py +++ b/func/Module_approximately_align.py @@ -1013,7 +1013,6 @@ class MainWindow_approximately_align(QMainWindow): return Result().failure(info=Constants.DRAW_FAILURE + "\n" + format_exc()) - class Data: def __init__(self): @@ -1027,7 +1026,6 @@ class Data: self.processed_downsample_Tho = None self.processed_downsample_Abd = None - def open_file(self): if Path(Config["Path"]["Input_orgBcg"]).is_file(): Config["Path"]["Input_orgBcg"] = str(Path(Config["Path"]["Input_orgBcg"]).parent)