Merge branch 'master' into cxh_dev
# Conflicts: # func/Module_approximately_align.py
This commit is contained in:
@ -15,9 +15,10 @@ from overrides import overrides
|
||||
from pandas import read_csv, DataFrame, Series, concat
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.Filters.Preprocessing import Butterworth_for_ECG_PreProcess
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
|
||||
from ui.MainWindow.MainWindow_SA_label import Ui_MainWindow_SA_label
|
||||
@ -98,36 +99,36 @@ class SettingWindow(QMainWindow):
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.SA_LABEL_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.SA_LABEL_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.SA_LABEL_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.SA_LABEL_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.SA_LABEL_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.SA_LABEL_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input_OrgBCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
"Input_OrgBCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Tho": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
"Input_Tho": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Abd": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_FlowT": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
"Input_Abd": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_FlowP": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
"Input_FlowT": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_SpO2": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Artifact": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Label": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
"Input_FlowP": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
"Input_SpO2": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Artifact": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Label": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_2": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
"Save_2": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID))))
|
||||
},
|
||||
"PlotEventIndex": 0,
|
||||
@ -182,7 +183,7 @@ class SettingWindow(QMainWindow):
|
||||
self.config["InputConfig"]["FlowPFreq"] = self.ui.spinBox_input_freq_signal_FlowP.value()
|
||||
self.config["InputConfig"]["SpO2Freq"] = self.ui.spinBox_input_freq_signal_SpO2.value()
|
||||
|
||||
with open(ConfigParams.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||||
with open(Params.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
@ -193,46 +194,46 @@ class SettingWindow(QMainWindow):
|
||||
def __update_ui__(self):
|
||||
self.ui.plainTextEdit_file_path_input_signal_OrgBCG.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ORGBCG_SYNC +
|
||||
Path(Filename.ORGBCG_SYNC +
|
||||
str(self.ui.spinBox_input_freq_signal_OrgBCG.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_signal_Tho.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.THO_SYNC +
|
||||
Path(Filename.THO_SYNC +
|
||||
str(self.ui.spinBox_input_freq_signal_Tho.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_signal_Abd.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ABD_SYNC +
|
||||
Path(Filename.ABD_SYNC +
|
||||
str(self.ui.spinBox_input_freq_signal_Abd.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_signal_FlowT.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.FLOWT_SYNC +
|
||||
Path(Filename.FLOWT_SYNC +
|
||||
str(self.ui.spinBox_input_freq_signal_FlowT.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_signal_FlowP.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.FLOWP_SYNC +
|
||||
Path(Filename.FLOWP_SYNC +
|
||||
str(self.ui.spinBox_input_freq_signal_FlowP.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_signal_SpO2.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.SPO2_SYNC +
|
||||
Path(Filename.SPO2_SYNC +
|
||||
str(self.ui.spinBox_input_freq_signal_SpO2.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
|
||||
|
||||
class MainWindow_SA_label(QMainWindow):
|
||||
@ -305,31 +306,31 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax2 = self.fig.add_subplot(self.gs[2], sharex=self.ax0)
|
||||
self.ax2.grid(True)
|
||||
self.ax2.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax2.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax3 = self.fig.add_subplot(self.gs[3], sharex=self.ax0)
|
||||
self.ax3.grid(True)
|
||||
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax4 = self.fig.add_subplot(self.gs[4], sharex=self.ax0)
|
||||
self.ax4.grid(True)
|
||||
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax5 = self.fig.add_subplot(self.gs[5], sharex=self.ax0)
|
||||
self.ax5.grid(True)
|
||||
self.ax5.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax5.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax6 = self.fig.add_subplot(self.gs[6], sharex=self.ax0)
|
||||
self.ax6.grid(True)
|
||||
self.ax6.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax6.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||||
|
||||
@ -378,17 +379,17 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.ui.checkBox_examineBySecond.clicked.connect(self.__slot_checkBox_examineBySecond__)
|
||||
self.ui.checkBox_examineLabeled.clicked.connect(self.__slot_checkBox_examineLabeled__)
|
||||
|
||||
self.ui.pushButton_prev.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_PREV_SHORTCUT_KEY))
|
||||
self.ui.pushButton_confirmLabel.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_CONFIRMLABEL_SHORTCUT_KEY))
|
||||
self.ui.pushButton_next.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_NEXT_SHORTCUT_KEY))
|
||||
self.ui.radioButton_OSA.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_OSA_SHORTCUT_KEY))
|
||||
self.ui.radioButton_CSA.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_CSA_SHORTCUT_KEY))
|
||||
self.ui.radioButton_MSA.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_MSA_SHORTCUT_KEY))
|
||||
self.ui.radioButton_HPY.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_HPY_SHORTCUT_KEY))
|
||||
self.ui.radioButton_1_class.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_1_CLASS_SHORTCUT_KEY))
|
||||
self.ui.radioButton_2_class.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_2_CLASS_SHORTCUT_KEY))
|
||||
self.ui.radioButton_3_class.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_3_CLASS_SHORTCUT_KEY))
|
||||
self.ui.pushButton_quick_remark_input_waitingForTalk.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_QUICK_REMARK_WAITINGFORTALK_SHORTCUT_KEY))
|
||||
self.ui.pushButton_prev.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_PREV_SHORTCUT_KEY))
|
||||
self.ui.pushButton_confirmLabel.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_CONFIRMLABEL_SHORTCUT_KEY))
|
||||
self.ui.pushButton_next.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_NEXT_SHORTCUT_KEY))
|
||||
self.ui.radioButton_OSA.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_OSA_SHORTCUT_KEY))
|
||||
self.ui.radioButton_CSA.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_CSA_SHORTCUT_KEY))
|
||||
self.ui.radioButton_MSA.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_MSA_SHORTCUT_KEY))
|
||||
self.ui.radioButton_HPY.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_HPY_SHORTCUT_KEY))
|
||||
self.ui.radioButton_1_class.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_1_CLASS_SHORTCUT_KEY))
|
||||
self.ui.radioButton_2_class.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_2_CLASS_SHORTCUT_KEY))
|
||||
self.ui.radioButton_3_class.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_3_CLASS_SHORTCUT_KEY))
|
||||
self.ui.pushButton_quick_remark_input_waitingForTalk.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_QUICK_REMARK_WAITINGFORTALK_SHORTCUT_KEY))
|
||||
|
||||
@overrides
|
||||
def closeEvent(self, event):
|
||||
@ -609,7 +610,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
item = QTableWidgetItem(str(correct_End))
|
||||
self.ui.tableWidget_label_add.setItem(index, 3, item)
|
||||
remark = row.get("remark", None)
|
||||
if str(remark) != "" and str(remark) != "nan" and row.get("isLabeled", None) == 1:
|
||||
if str(remark) != Constants.STRING_IS_EMPTY and str(remark) != Constants.STRING_IS_NAN and row.get("isLabeled", None) == 1:
|
||||
for col in range(self.ui.tableWidget_label_add.columnCount()):
|
||||
item = self.ui.tableWidget_label_add.item(index, col)
|
||||
item.setBackground(QColor(255, 200, 200))
|
||||
@ -1000,33 +1001,40 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.ui.spinBox_correctEnd.setValue(Config["BCG_EP"])
|
||||
|
||||
def reset_axes(self):
|
||||
self.ax0.clear()
|
||||
self.ax1.clear()
|
||||
self.ax2.clear()
|
||||
self.ax3.clear()
|
||||
self.ax4.clear()
|
||||
self.ax5.clear()
|
||||
self.ax6.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax2.grid(True)
|
||||
self.ax2.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax2.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax3.grid(True)
|
||||
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax4.grid(True)
|
||||
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax5.grid(True)
|
||||
self.ax5.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax6.grid(True)
|
||||
self.ax6.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
if self.ax1 is not None:
|
||||
self.ax1.clear()
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
if self.ax2 is not None:
|
||||
self.ax2.clear()
|
||||
self.ax2.grid(True)
|
||||
self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax2.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
if self.ax3 is not None:
|
||||
self.ax3.clear()
|
||||
self.ax3.grid(True)
|
||||
self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
if self.ax4 is not None:
|
||||
self.ax4.clear()
|
||||
self.ax4.grid(True)
|
||||
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
if self.ax5 is not None:
|
||||
self.ax5.clear()
|
||||
self.ax5.grid(True)
|
||||
self.ax5.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
if self.ax6 is not None:
|
||||
self.ax6.clear()
|
||||
self.ax6.grid(True)
|
||||
self.ax6.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
def on_xlim_change(self, event_ax):
|
||||
# 获取当前x轴范围
|
||||
@ -1155,7 +1163,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"],
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
|
||||
color='red',
|
||||
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
|
||||
alpha=Params.SA_LABEL_TRANSPARENCY)
|
||||
elif self.data.df_corrected.at[
|
||||
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Central apnea":
|
||||
for ax in ax_:
|
||||
@ -1163,7 +1171,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"],
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
|
||||
color='blue',
|
||||
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
|
||||
alpha=Params.SA_LABEL_TRANSPARENCY)
|
||||
elif self.data.df_corrected.at[
|
||||
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Mixed apnea":
|
||||
for ax in ax_:
|
||||
@ -1171,7 +1179,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"],
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
|
||||
color='gray',
|
||||
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
|
||||
alpha=Params.SA_LABEL_TRANSPARENCY)
|
||||
elif self.data.df_corrected.at[
|
||||
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Hypopnea":
|
||||
for ax in ax_:
|
||||
@ -1179,7 +1187,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"],
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
|
||||
color='pink',
|
||||
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
|
||||
alpha=Params.SA_LABEL_TRANSPARENCY)
|
||||
else:
|
||||
if self.data.df_corrected.at[
|
||||
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Obstructive apnea":
|
||||
@ -1187,28 +1195,28 @@ class MainWindow_SA_label(QMainWindow):
|
||||
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
|
||||
color='red',
|
||||
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
|
||||
alpha=Params.SA_LABEL_TRANSPARENCY)
|
||||
elif self.data.df_corrected.at[
|
||||
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Central apnea":
|
||||
for ax in ax_:
|
||||
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
|
||||
color='blue',
|
||||
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
|
||||
alpha=Params.SA_LABEL_TRANSPARENCY)
|
||||
elif self.data.df_corrected.at[
|
||||
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Mixed apnea":
|
||||
for ax in ax_:
|
||||
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
|
||||
color='gray',
|
||||
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
|
||||
alpha=Params.SA_LABEL_TRANSPARENCY)
|
||||
elif self.data.df_corrected.at[
|
||||
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Hypopnea":
|
||||
for ax in ax_:
|
||||
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
|
||||
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
|
||||
color='pink',
|
||||
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
|
||||
alpha=Params.SA_LABEL_TRANSPARENCY)
|
||||
|
||||
def pd_add_new_row(self, df, score: int, remark: str, correct_Start: int, correct_End: int, correct_EventsType: str,
|
||||
isLabeled: int):
|
||||
@ -1259,7 +1267,7 @@ class Data:
|
||||
|
||||
def open_file(self):
|
||||
if Path(Config["Path"]["Input_OrgBCG"]).is_file():
|
||||
Config["Path"]["Input_OrgBCG"] = str(Path(Config["Path"]["Input_orgBcg"]).parent)
|
||||
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():
|
||||
@ -1275,84 +1283,88 @@ class Data:
|
||||
if Path(Config["Path"]["Input_Label"]).is_file():
|
||||
Config["Path"]["Input_Label"] = str(Path(Config["Path"]["Input_Label"]).parent)
|
||||
|
||||
if ((not Path(Config["Path"]["Input_OrgBCG"]).exists())
|
||||
or (not Path(Config["Path"]["Input_Tho"]).exists())
|
||||
or (not Path(Config["Path"]["Input_Abd"]).exists())
|
||||
or (not Path(Config["Path"]["Input_FlowT"]).exists())
|
||||
or (not Path(Config["Path"]["Input_FlowP"]).exists())
|
||||
or (not Path(Config["Path"]["Input_SpO2"]).exists())
|
||||
or (not Path(Config["Path"]["Input_Artifact"]).exists())):
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], ConfigParams.ORGBCG_SYNC)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_OrgBCG"] = result.data["path"]
|
||||
Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], ConfigParams.THO_SYNC)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_SYNC, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_Tho"] = result.data["path"]
|
||||
Config["InputConfig"]["ThoFreq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], ConfigParams.ABD_SYNC)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], Filename.ABD_SYNC, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_Abd"] = result.data["path"]
|
||||
Config["InputConfig"]["AbdFreq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_FlowT"], ConfigParams.FLOWT_SYNC)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_FlowT"], Filename.FLOWT_SYNC, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_FlowT"] = result.data["path"]
|
||||
Config["InputConfig"]["FlowTFreq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_FlowP"], ConfigParams.FLOWP_SYNC)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_FlowP"], Filename.FLOWP_SYNC, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_FlowP"] = result.data["path"]
|
||||
Config["InputConfig"]["FlowPFreq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_SpO2"], ConfigParams.SPO2_SYNC)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_SpO2"], Filename.SPO2_SYNC, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_SpO2"] = result.data["path"]
|
||||
Config["InputConfig"]["SpO2Freq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Artifact"], Filename.ARTIFACT_A, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_Artifact"] = result.data["path"]
|
||||
else:
|
||||
return result
|
||||
|
||||
Config["Path"]["Input_Artifact"] = str(
|
||||
Path(Config["Path"]["Input_Artifact"]) / Path(ConfigParams.ARTIFACT_A + ConfigParams.ENDSWITH_TXT))
|
||||
Config["Path"]["Input_Label"] = str(
|
||||
Path(Config["Path"]["Input_Label"]) / Path(ConfigParams.SA_LABEL_SYNC + ConfigParams.ENDSWITH_CSV))
|
||||
Path(Config["Path"]["Input_Label"]) / Path(Filename.SA_LABEL_SYNC + Params.ENDSWITH_CSV))
|
||||
Config["Path"]["Save"] = str(
|
||||
Path(Config["Path"]["Save"]) / Path(ConfigParams.SA_LABEL_CORRECTED + ConfigParams.ENDSWITH_CSV))
|
||||
Path(Config["Path"]["Save"]) / Path(Filename.SA_LABEL_CORRECTED + Params.ENDSWITH_CSV))
|
||||
Config["Path"]["Save_2"] = str(
|
||||
Path(Config["Path"]["Save_2"]) / Path(ConfigParams.SA_LABEL_ADD + ConfigParams.ENDSWITH_CSV))
|
||||
Path(Config["Path"]["Save_2"]) / Path(Filename.SA_LABEL_ADD + Params.ENDSWITH_CSV))
|
||||
|
||||
if not Path(Config["Path"]["Input_Artifact"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
Filename.ARTIFACT_A + ":" +
|
||||
Config["Path"]["Input_Artifact"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
if not Path(Config["Path"]["Input_Label"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
Filename.SA_LABEL_SYNC + ":" +
|
||||
Config["Path"]["Input_Label"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
try:
|
||||
self.OrgBCG = read_csv(Config["Path"]["Input_OrgBCG"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.Tho = read_csv(Config["Path"]["Input_Tho"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.Abd = read_csv(Config["Path"]["Input_Abd"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.FlowT = read_csv(Config["Path"]["Input_FlowT"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.FlowP = read_csv(Config["Path"]["Input_FlowP"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.SpO2 = read_csv(Config["Path"]["Input_SpO2"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.Artifact = read_csv(Config["Path"]["Input_Artifact"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.event_label = zeros(len(self.OrgBCG) + (int(Config["AddSecond"]["Front"] + int(Config["AddSecond"]["Back"])) * Config["InputConfig"]["PlotFreq"]))
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
@ -1360,13 +1372,7 @@ class Data:
|
||||
|
||||
try:
|
||||
# 检查体动标签正确性,长度
|
||||
if len(self.Artifact) % 4 != 0:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
Constants.FAILURE_REASON["Artifact_Format_Not_Correct"])
|
||||
for i in range(0, len(self.Artifact), 4):
|
||||
unit_data = self.Artifact[i:i + 4]
|
||||
if len(unit_data) < 4:
|
||||
break
|
||||
PublicFunc.examine_artifact(self.Artifact)
|
||||
self.Artifact = self.Artifact.reshape(-1, 4)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
@ -1584,9 +1590,6 @@ class Data:
|
||||
return Result().success(info=Constants.RESAMPLE_FINISHED)
|
||||
|
||||
def save(self):
|
||||
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if self.df_corrected is None:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
|
||||
@ -1618,6 +1621,6 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
|
||||
def __init__(self, canvas, parent):
|
||||
super().__init__(canvas, parent)
|
||||
self.action_Reset_Signal_and_Time = QAction('复原视图和时间', self)
|
||||
self.action_Reset_Signal_and_Time.setFont(QFont(ConfigParams.FONT, 14))
|
||||
self.action_Reset_Signal_and_Time.setFont(QFont(Params.FONT, 14))
|
||||
self.action_Reset_Signal_and_Time.setCheckable(True)
|
||||
self.insertAction(self._actions['home'], self.action_Reset_Signal_and_Time)
|
||||
@ -13,8 +13,10 @@ 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.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
|
||||
from ui.MainWindow.MainWindow_approximately_align import Ui_MainWindow_approximately_align
|
||||
@ -99,11 +101,11 @@ class SettingWindow(QMainWindow):
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
@ -112,15 +114,15 @@ class SettingWindow(QMainWindow):
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input_orgBcg": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Input_orgBcg": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Tho": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Input_Tho": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Abd": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Input_Abd": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) / Path(ConfigParams.APPROXIMATELY_ALIGN_INFO +
|
||||
ConfigParams.ENDSWITH_CSV)))
|
||||
"Save": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)) / Path(Filename.APPROXIMATELY_ALIGN_INFO +
|
||||
Params.ENDSWITH_CSV)))
|
||||
},
|
||||
"orgBcgConfig": {},
|
||||
"PSGConfig": {}
|
||||
@ -162,7 +164,7 @@ class SettingWindow(QMainWindow):
|
||||
self.config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandpassLow.value()
|
||||
self.config["Filter"]["BandPassHigh"] = self.ui.doubleSpinBox_bandpassHigh.value()
|
||||
|
||||
with open(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
|
||||
with open(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
@ -173,31 +175,25 @@ class SettingWindow(QMainWindow):
|
||||
def __update_ui__(self):
|
||||
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ORGBCG_RAW +
|
||||
Path(Filename.ORGBCG_RAW +
|
||||
str(self.ui.spinBox_input_orgBcg_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_Tho.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.THO_RAW +
|
||||
Path(Filename.THO_RAW +
|
||||
str(self.ui.spinBox_input_Tho_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_Abd.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ABD_RAW +
|
||||
Path(Filename.ABD_RAW +
|
||||
str(self.ui.spinBox_input_Abd_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.APPROXIMATELY_ALIGN_INFO +
|
||||
ConfigParams.ENDSWITH_CSV))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
|
||||
|
||||
class MainWindow_approximately_align(QMainWindow):
|
||||
@ -998,19 +994,19 @@ class Data:
|
||||
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"], ConfigParams.ORGBCG_RAW)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_RAW, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_orgBcg"] = result.data["path"]
|
||||
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], ConfigParams.THO_RAW)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_RAW, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_Tho"] = result.data["path"]
|
||||
Config["InputConfig"]["ThoFreq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], ConfigParams.ABD_RAW)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], Filename.ABD_RAW, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_Abd"] = result.data["path"]
|
||||
Config["InputConfig"]["AbdFreq"] = result.data["freq"]
|
||||
@ -1019,13 +1015,13 @@ class Data:
|
||||
|
||||
try:
|
||||
self.raw_orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.raw_Tho = read_csv(Config["Path"]["Input_Tho"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.raw_Abd = read_csv(Config["Path"]["Input_Abd"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON[
|
||||
@ -1034,8 +1030,6 @@ class Data:
|
||||
return Result().success(info=Constants.INPUT_FINISHED)
|
||||
|
||||
def save(self, epoch):
|
||||
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
pos = Config["pos"]
|
||||
ApplyFrequency = Config["ApplyFrequency"]
|
||||
@ -1120,10 +1114,7 @@ class Data:
|
||||
def Standardize_2(self):
|
||||
# 预重采样
|
||||
try:
|
||||
# TODO:这里的采样率处理,如果THO和ABD的采样率不同,可能还是会导致之后的ApplyFrequency出问题,最后导致得到的粗同步坐标不正确
|
||||
#
|
||||
if Config["InputConfig"]["ThoFreq"] != Config["TempFrequency"]:
|
||||
print(int(Config["InputConfig"]["ThoFreq"]), int(Config["TempFrequency"]))
|
||||
self.processed_Tho = resample(self.processed_Tho,
|
||||
int(Config["PSG_seconds"] * Config["TempFrequency"]))
|
||||
|
||||
@ -1198,7 +1189,7 @@ class Data:
|
||||
# 计算互相关1/2
|
||||
try:
|
||||
# 计算因子
|
||||
MULTIPLE_FACTOER = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Multiple_Factor"]
|
||||
MULTIPLE_FACTOER = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Multiple_Factor"]
|
||||
a = self.processed_downsample_Tho[
|
||||
Config["PSGConfig"]["PreCut"]:len(self.processed_downsample_Tho) - Config["PSGConfig"][
|
||||
"PostCut"]].copy()
|
||||
@ -1293,8 +1284,8 @@ class Data:
|
||||
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"]
|
||||
temp_freq = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"]
|
||||
window_epoch = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["CorrByEpoch"]["window_epoch"]
|
||||
tho_bias_list = []
|
||||
abd_bias_list = []
|
||||
|
||||
|
||||
@ -9,15 +9,16 @@ from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication, QTableWidg
|
||||
from matplotlib import gridspec, patches
|
||||
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
||||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
||||
from numpy import array, append
|
||||
from numpy import array, append, sum as np_sum, nonzero
|
||||
from numpy.fft import fft, fftfreq
|
||||
from overrides import overrides
|
||||
from pandas import read_csv, DataFrame, concat
|
||||
from scipy.signal import resample
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
|
||||
from ui.MainWindow.MainWindow_artifact_label import Ui_MainWindow_artifact_label
|
||||
@ -35,7 +36,6 @@ ButtonState = {
|
||||
"pushButton_prev_move": False,
|
||||
"pushButton_pause": False,
|
||||
"pushButton_next_move": False,
|
||||
"pushButton_save": False,
|
||||
"pushButton_type_1": False,
|
||||
"pushButton_type_2": False,
|
||||
"pushButton_type_3": False,
|
||||
@ -49,7 +49,6 @@ ButtonState = {
|
||||
"pushButton_prev_move": False,
|
||||
"pushButton_pause": False,
|
||||
"pushButton_next_move": False,
|
||||
"pushButton_save": False,
|
||||
"pushButton_type_1": False,
|
||||
"pushButton_type_2": False,
|
||||
"pushButton_type_3": False,
|
||||
@ -80,26 +79,26 @@ class SettingWindow(QMainWindow):
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.ARTIFACT_LABEL_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.ARTIFACT_LABEL_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input_orgBcg": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
"Input_orgBcg": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
"Input_BCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_a": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
"Save_a": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_b": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
"Save_b": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_c": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
"Save_c": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID))))
|
||||
}
|
||||
})
|
||||
@ -127,7 +126,7 @@ class SettingWindow(QMainWindow):
|
||||
self.config["InputConfig"]["orgBcgFreq"] = self.ui.spinBox_input_freq_orgBcg.value()
|
||||
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.value()
|
||||
|
||||
with open(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||||
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
@ -138,18 +137,18 @@ class SettingWindow(QMainWindow):
|
||||
def __update_ui__(self):
|
||||
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ORGBCG_SYNC +
|
||||
Path(Filename.ORGBCG_SYNC +
|
||||
str(self.ui.spinBox_input_freq_orgBcg.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_BCG.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.BCG_SYNC +
|
||||
Path(Filename.BCG_SYNC +
|
||||
str(self.ui.spinBox_input_freq_BCG.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
|
||||
|
||||
class MainWindow_artifact_label(QMainWindow):
|
||||
@ -233,11 +232,11 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||||
|
||||
@ -261,8 +260,8 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
self.ui.tableWidget_type_4.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||
self.ui.tableWidget_type_5.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||
|
||||
self.ui.lineEdit_start_time.setValidator(ConfigParams.VALIDATOR_INTEGER)
|
||||
self.ui.lineEdit_end_time.setValidator(ConfigParams.VALIDATOR_INTEGER)
|
||||
self.ui.lineEdit_start_time.setValidator(Params.VALIDATOR_INTEGER)
|
||||
self.ui.lineEdit_end_time.setValidator(Params.VALIDATOR_INTEGER)
|
||||
|
||||
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
|
||||
self.ui.pushButton_type_1.clicked.connect(self.__slot_btn_label__)
|
||||
@ -270,7 +269,6 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
self.ui.pushButton_type_3.clicked.connect(self.__slot_btn_label__)
|
||||
self.ui.pushButton_type_4.clicked.connect(self.__slot_btn_label__)
|
||||
self.ui.pushButton_type_5.clicked.connect(self.__slot_btn_label__)
|
||||
self.ui.pushButton_save.clicked.connect(self.__slot_btn_save__)
|
||||
self.ui.pushButton_delete.clicked.connect(self.__slot_btn_delete_label__)
|
||||
self.ui.pushButton_prev_move.clicked.connect(self.__slot_btn_move__)
|
||||
self.ui.pushButton_pause.clicked.connect(self.__slot_btn_move__)
|
||||
@ -300,8 +298,10 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
del self.rectangles_ax0_patches
|
||||
del self.rectangles_ax1_patches
|
||||
del self.annotation_tableWidget
|
||||
self.ax0.clear()
|
||||
self.ax1.clear()
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
if self.ax1 is not None:
|
||||
self.ax1.clear()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
@ -370,71 +370,71 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
if self.data.df_Artifact_a.iloc[i][1] == 1:
|
||||
# 橙色,剧烈体动
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_DEEP_YELLOW)
|
||||
self.rectangles_ax0_patches.append(rectangle)
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_DEEP_YELLOW)
|
||||
self.rectangles_ax1_patches.append(rectangle)
|
||||
elif self.data.df_Artifact_a.iloc[i][1] == 2:
|
||||
# 黄色,脉冲体动
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_YELLOW)
|
||||
self.rectangles_ax0_patches.append(rectangle)
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_YELLOW)
|
||||
self.rectangles_ax1_patches.append(rectangle)
|
||||
elif self.data.df_Artifact_a.iloc[i][1] == 3:
|
||||
# 青色,常规体动
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_AQUA)
|
||||
self.rectangles_ax0_patches.append(rectangle)
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_AQUA)
|
||||
self.rectangles_ax1_patches.append(rectangle)
|
||||
elif self.data.df_Artifact_a.iloc[i][1] == 4:
|
||||
# 紫色,疑似鼾声
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PURPLE_PINK)
|
||||
self.rectangles_ax0_patches.append(rectangle)
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PURPLE_PINK)
|
||||
self.rectangles_ax1_patches.append(rectangle)
|
||||
elif self.data.df_Artifact_a.iloc[i][1] == 5:
|
||||
# 灰色,离床
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_DEEP_GREY)
|
||||
self.rectangles_ax0_patches.append(rectangle)
|
||||
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
|
||||
height=self.rect_up - self.rect_down,
|
||||
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_DEEP_GREY)
|
||||
self.rectangles_ax1_patches.append(rectangle)
|
||||
for patch in self.rectangles_ax0_patches:
|
||||
@ -560,7 +560,7 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.UPDATE_FAILURE + Constants.FAILURE_REASON["Update_Info_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.UPDATE_FAILURE)
|
||||
return Result().success(info=Constants.UPDATE_FINISHED)
|
||||
|
||||
def __slot_btn_input__(self):
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
@ -592,9 +592,6 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
self.__reset__()
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
# 获取存档
|
||||
PublicFunc.progressbar_update(self, 3, 6, Constants.LOADING_ARCHIVE, 50)
|
||||
result = self.data.get_archive()
|
||||
@ -648,7 +645,6 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
ButtonState["Current"]["pushButton_prev_move"] = True
|
||||
ButtonState["Current"]["pushButton_next_move"] = True
|
||||
ButtonState["Current"]["pushButton_pause"] = True
|
||||
ButtonState["Current"]["pushButton_save"] = True
|
||||
ButtonState["Current"]["pushButton_type_1"] = True
|
||||
ButtonState["Current"]["pushButton_type_2"] = True
|
||||
ButtonState["Current"]["pushButton_type_3"] = True
|
||||
@ -659,7 +655,12 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
def __slot_btn_label__(self):
|
||||
sender = self.sender()
|
||||
flag = False
|
||||
select_row = array([]).astype(dict)
|
||||
select_row = []
|
||||
select_type = array([0, 0, 0, 0, 0])
|
||||
flagf = False
|
||||
flagb = False
|
||||
start_time = 0
|
||||
end_time = 0
|
||||
|
||||
if sender == self.ui.pushButton_type_1:
|
||||
type = 1
|
||||
@ -682,65 +683,153 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
for index, row in self.data.df_Artifact_a.iterrows():
|
||||
value_startTime = row['startTime']
|
||||
value_endTime = row['endTime']
|
||||
value_type = row['type']
|
||||
|
||||
# if ((value_endTime >= int(self.ui.lineEdit_start_time.text()) and value_startTime <= int(self.ui.lineEdit_start_time.text())) or
|
||||
# (value_endTime >= int(self.ui.lineEdit_end_time.text()) and value_startTime <= int(self.ui.lineEdit_end_time.text())) or
|
||||
# (value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(self.ui.lineEdit_end_time.text())) or
|
||||
# (value_startTime <= int(self.ui.lineEdit_start_time.text()) and value_endTime >= int(self.ui.lineEdit_end_time.text()))):
|
||||
# select_row = append(select_row, row)
|
||||
if ((value_startTime <= int(self.ui.lineEdit_end_time.text()) <= value_endTime) or
|
||||
(value_startTime <= int(self.ui.lineEdit_start_time.text()) <= value_endTime) or
|
||||
(value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(self.ui.lineEdit_end_time.text())) or
|
||||
(0 < (int(self.ui.lineEdit_start_time.text()) - value_endTime) <= (2 * Config["InputConfig"]["UseFreq"])) or
|
||||
(0 < (value_startTime - int(self.ui.lineEdit_end_time.text())) <= (2 * Config["InputConfig"]["UseFreq"]))):
|
||||
select_row.append(row.to_dict())
|
||||
if row['type'] == 1:
|
||||
select_type[0] = select_type[0] + 1
|
||||
elif row['type'] == 2:
|
||||
select_type[1] = select_type[1] + 1
|
||||
elif row['type'] == 3:
|
||||
select_type[2] = select_type[2] + 1
|
||||
elif row['type'] == 4:
|
||||
select_type[3] = select_type[3] + 1
|
||||
elif row['type'] == 5:
|
||||
select_type[4] = select_type[4] + 1
|
||||
if (0 < (int(self.ui.lineEdit_start_time.text()) - value_endTime) <= (2 * Config["InputConfig"]["UseFreq"])) and (value_type == type):
|
||||
flagf = True
|
||||
if (0 < (value_startTime - int(self.ui.lineEdit_end_time.text())) <= (2 * Config["InputConfig"]["UseFreq"])) and (value_type == type):
|
||||
flagb = True
|
||||
|
||||
# TODO:体动选取区域的判别尚未做的很完整,选中多个已有的体动的区域时可能会出现问题
|
||||
if (type == 1 and row['type'] == 1) or (type == 2 and row['type'] == 2) or (type == 3 and row['type'] == 3):
|
||||
if ((value_startTime > int(self.ui.lineEdit_start_time.text()) and (value_startTime - int(self.ui.lineEdit_end_time.text()) <= 2 * Config["InputConfig"]["UseFreq"])) or
|
||||
(value_endTime < int(self.ui.lineEdit_end_time.text()) and (int(self.ui.lineEdit_end_time.text()) - value_endTime <= 2 * Config["InputConfig"]["UseFreq"]))):
|
||||
reply = QMessageBox.question(self, '确认', '{}{},是否确认合并?'.format(Constants.ARTIFACT_LABEL_MERGE, row['number']), QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.No)
|
||||
if reply == QMessageBox.Yes:
|
||||
self.data.df_Artifact_a.loc[self.data.df_Artifact_a['number'] == row['number'],
|
||||
['number', 'type', 'startTime', 'endTime']] = [
|
||||
int(row['number']),
|
||||
int(type),
|
||||
int(self.ui.lineEdit_start_time.text()) if int(self.ui.lineEdit_start_time.text()) < int(row['startTime']) else int(row['startTime']),
|
||||
int(self.ui.lineEdit_end_time.text()) if int(self.ui.lineEdit_end_time.text()) > int(row['endTime']) else int(row['endTime'])
|
||||
]
|
||||
new_row = {'number': int(row['number']),
|
||||
'type': int(type),
|
||||
'startTime': int(self.ui.lineEdit_start_time.text()),
|
||||
'endTime': int(self.ui.lineEdit_end_time.text())}
|
||||
flag = True
|
||||
break
|
||||
else:
|
||||
return
|
||||
if value_startTime <= int(self.ui.lineEdit_end_time.text()) and int(
|
||||
self.ui.lineEdit_start_time.text()) <= value_endTime:
|
||||
PublicFunc.msgbox_output(self, f"{Constants.ARTIFACT_LABEL_OVERLAPPING}{row['number']}", Constants.MSGBOX_TYPE_ERROR)
|
||||
return
|
||||
count = np_sum(select_type >= 1)
|
||||
if count >= 2 or (count == 1 and nonzero(select_type)[0][0] + 1 == type):
|
||||
if count >= 2:
|
||||
reply = QMessageBox.question(self, '确认',
|
||||
'{}{}'.format(Constants.ARTIFACT_LABEL_MULTIPLE_ARTIFACT_COVER_OR_DELETE, [d["number"] for d in select_row]),
|
||||
QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.No)
|
||||
if reply == QMessageBox.No:
|
||||
return
|
||||
|
||||
if not flag:
|
||||
new_row = {'number': int(len(self.data.df_Artifact_a) + 1),
|
||||
'type': int(type),
|
||||
'startTime': int(self.ui.lineEdit_start_time.text()),
|
||||
'endTime': int(self.ui.lineEdit_end_time.text())}
|
||||
self.data.df_Artifact_a = concat([self.data.df_Artifact_a, DataFrame([new_row])], ignore_index=True)
|
||||
sorted_part = self.data.df_Artifact_a[['type', 'startTime', 'endTime']].sort_values(by='startTime').reset_index(
|
||||
if flagf == True and flagb == False:
|
||||
if type == 1 or type == 2 or type == 3:
|
||||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE,
|
||||
Constants.MSGBOX_TYPE_INFO)
|
||||
start_time = select_row[0]['startTime']
|
||||
end_time = int(self.ui.lineEdit_end_time.text())
|
||||
elif type == 4 or type == 5:
|
||||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_WARNING,
|
||||
Constants.MSGBOX_TYPE_INFO)
|
||||
select_row = select_row[1:]
|
||||
start_time = int(self.ui.lineEdit_start_time.text())
|
||||
end_time = int(self.ui.lineEdit_end_time.text())
|
||||
if flagf == False and flagb == True:
|
||||
if type == 1 or type == 2 or type == 3:
|
||||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE,
|
||||
Constants.MSGBOX_TYPE_INFO)
|
||||
start_time = int(self.ui.lineEdit_start_time.text())
|
||||
end_time = select_row[-1]['endTime']
|
||||
elif type == 4 or type == 5:
|
||||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_WARNING,
|
||||
Constants.MSGBOX_TYPE_INFO)
|
||||
select_row = select_row[:-1]
|
||||
start_time = int(self.ui.lineEdit_start_time.text())
|
||||
end_time = int(self.ui.lineEdit_end_time.text())
|
||||
if flagf == True and flagb == True:
|
||||
if type == 1 or type == 2 or type == 3:
|
||||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE,
|
||||
Constants.MSGBOX_TYPE_INFO)
|
||||
start_time = select_row[0]['startTime']
|
||||
end_time = select_row[-1]['endTime']
|
||||
elif type == 4 or type == 5:
|
||||
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_WARNING,
|
||||
Constants.MSGBOX_TYPE_INFO)
|
||||
select_row = select_row[1:-1]
|
||||
start_time = int(self.ui.lineEdit_start_time.text())
|
||||
end_time = int(self.ui.lineEdit_end_time.text())
|
||||
if flagf == False and flagb == False:
|
||||
start_time = int(self.ui.lineEdit_start_time.text())
|
||||
end_time = int(self.ui.lineEdit_end_time.text())
|
||||
|
||||
for select_each_row in select_row:
|
||||
self.data.df_Artifact_a = self.data.df_Artifact_a[self.data.df_Artifact_a['number'] != select_each_row["number"]]
|
||||
else:
|
||||
select_row = []
|
||||
select_type = array([0, 0, 0, 0, 0])
|
||||
for index, row in self.data.df_Artifact_a.iterrows():
|
||||
value_startTime = row['startTime']
|
||||
value_endTime = row['endTime']
|
||||
value_type = row['type']
|
||||
if ((value_startTime <= int(self.ui.lineEdit_end_time.text()) <= value_endTime) or
|
||||
(value_startTime <= int(self.ui.lineEdit_start_time.text()) <= value_endTime) or
|
||||
(value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(
|
||||
self.ui.lineEdit_end_time.text()))):
|
||||
select_row.append(row.to_dict())
|
||||
if row['type'] == 1:
|
||||
select_type[0] = select_type[0] + 1
|
||||
elif row['type'] == 2:
|
||||
select_type[1] = select_type[1] + 1
|
||||
elif row['type'] == 3:
|
||||
select_type[2] = select_type[2] + 1
|
||||
elif row['type'] == 4:
|
||||
select_type[3] = select_type[3] + 1
|
||||
elif row['type'] == 5:
|
||||
select_type[4] = select_type[4] + 1
|
||||
|
||||
count = np_sum(select_type >= 1)
|
||||
|
||||
if (count == 1 and nonzero(select_type)[0][0] + 1 != type):
|
||||
reply = QMessageBox.question(self, '确认',
|
||||
'{}{}'.format(Constants.ARTIFACT_LABEL_SINGLE_TYPE_NOT_EQUAL,
|
||||
[d["number"] for d in select_row]),
|
||||
QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.No)
|
||||
if reply == QMessageBox.No:
|
||||
return
|
||||
|
||||
start_time = int(self.ui.lineEdit_start_time.text())
|
||||
end_time = int(self.ui.lineEdit_end_time.text())
|
||||
|
||||
for select_each_row in select_row:
|
||||
self.data.df_Artifact_a = self.data.df_Artifact_a[self.data.df_Artifact_a['number'] != select_each_row["number"]]
|
||||
elif count == 0:
|
||||
start_time = int(self.ui.lineEdit_start_time.text())
|
||||
end_time = int(self.ui.lineEdit_end_time.text())
|
||||
else:
|
||||
raise ValueError("count值不存在")
|
||||
|
||||
new_row = {
|
||||
'number': 1,
|
||||
'type': int(type),
|
||||
'startTime': start_time,
|
||||
'endTime': end_time
|
||||
}
|
||||
|
||||
self.data.df_Artifact_a = concat([self.data.df_Artifact_a, DataFrame([new_row])], ignore_index=True)
|
||||
self.data.df_Artifact_a[['type', 'startTime', 'endTime']] = self.data.df_Artifact_a[['type', 'startTime', 'endTime']].sort_values(by='startTime').reset_index(
|
||||
drop=True)
|
||||
self.data.df_Artifact_a[['type', 'startTime', 'endTime']] = sorted_part
|
||||
self.data.df_Artifact_a['number'] = range(1, len(self.data.df_Artifact_a) + 1)
|
||||
|
||||
self.update_tableWidget()
|
||||
self.update_Info()
|
||||
self.__plot_artifact__()
|
||||
|
||||
target_row = self.data.df_Artifact_a[
|
||||
self.data.df_Artifact_a.eq(int(self.ui.lineEdit_start_time.text())).any(axis=1)]
|
||||
target_row = self.data.df_Artifact_a[self.data.df_Artifact_a.eq(start_time).any(axis=1)]
|
||||
if not target_row.empty:
|
||||
first_column_value = target_row.iloc[0, 0] # 获取第1列的值
|
||||
else:
|
||||
raise AttributeError()
|
||||
|
||||
PublicFunc.text_output(self.ui, f"新增体动标签{first_column_value}, 类型{new_row['type']},从{int(self.ui.lineEdit_start_time.text())}ms到{int(self.ui.lineEdit_end_time.text())}ms", Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, f"新增体动标签{first_column_value}, 类型{new_row['type']},从{int(start_time)}ms到{int(end_time)}ms", Constants.TIPS_TYPE_INFO)
|
||||
|
||||
self.__slot_btn_save__()
|
||||
self.save()
|
||||
|
||||
def __slot_btn_save__(self):
|
||||
def save(self):
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
|
||||
# 保存
|
||||
@ -791,7 +880,7 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
self.update_tableWidget()
|
||||
self.update_Info()
|
||||
self.__plot_artifact__()
|
||||
self.__slot_btn_save__()
|
||||
self.save()
|
||||
PublicFunc.text_output(self.ui, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY}", Constants.TIPS_TYPE_INFO)
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE}", Constants.TIPS_TYPE_ERROR)
|
||||
@ -929,13 +1018,15 @@ class MainWindow_artifact_label(QMainWindow):
|
||||
PublicFunc.text_output(self.ui, f"{Constants.ARTIFACT_LABEL_JUMP_ARTIFACT}{str(self.pressed_number)}", Constants.TIPS_TYPE_INFO)
|
||||
|
||||
def reset_axes(self):
|
||||
self.ax0.clear()
|
||||
self.ax1.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
if self.ax1 is not None:
|
||||
self.ax1.clear()
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
def on_xlim_change(self, event_ax):
|
||||
try:
|
||||
@ -1208,17 +1299,14 @@ class Data:
|
||||
if Path(Config["Path"]["Input_BCG"]).is_file():
|
||||
Config["Path"]["Input_BCG"] = str(Path(Config["Path"]["Input_BCG"]).parent)
|
||||
|
||||
if (not Path(Config["Path"]["Input_orgBcg"]).exists()) or (not Path(Config["Path"]["Input_BCG"]).exists()):
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], ConfigParams.ORGBCG_SYNC)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_orgBcg"] = result.data["path"]
|
||||
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
|
||||
else:
|
||||
return result
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], ConfigParams.BCG_SYNC)
|
||||
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"]["BCGFreq"] = result.data["freq"]
|
||||
@ -1226,18 +1314,18 @@ class Data:
|
||||
return result
|
||||
|
||||
Config["Path"]["Save_a"] = str(
|
||||
Path(Config["Path"]["Save_a"]) / Path(ConfigParams.ARTIFACT_A + ConfigParams.ENDSWITH_TXT))
|
||||
Path(Config["Path"]["Save_a"]) / Path(Filename.ARTIFACT_A + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_b"] = str(
|
||||
Path(Config["Path"]["Save_b"]) / Path(ConfigParams.ARTIFACT_B + ConfigParams.ENDSWITH_TXT))
|
||||
Path(Config["Path"]["Save_b"]) / Path(Filename.ARTIFACT_B + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_c"] = str(
|
||||
Path(Config["Path"]["Save_c"]) / Path(ConfigParams.ARTIFACT_C + ConfigParams.ENDSWITH_CSV))
|
||||
Path(Config["Path"]["Save_c"]) / Path(Filename.ARTIFACT_C + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_CSV))
|
||||
|
||||
try:
|
||||
self.orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.BCG = read_csv(Config["Path"]["Input_BCG"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
|
||||
@ -1271,7 +1359,7 @@ class Data:
|
||||
return Result().success(info=Constants.ARCHIVE_NOT_EXIST)
|
||||
else:
|
||||
self.Artifact_a = read_csv(Config["Path"]["Save_a"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
try:
|
||||
# 检查体动标签正确性,长度
|
||||
@ -1290,13 +1378,6 @@ class Data:
|
||||
return Result().success(info=Constants.ARCHIVE_EXIST)
|
||||
|
||||
def save(self, amount, duration):
|
||||
if (not Path(Config["Path"]["Save_a"]).parent.exists()) or (not Path(Config["Path"]["Save_a"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save_a"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
if (not Path(Config["Path"]["Save_b"]).parent.exists()) or (not Path(Config["Path"]["Save_b"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save_b"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
if (not Path(Config["Path"]["Save_c"]).parent.exists()) or (not Path(Config["Path"]["Save_c"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save_c"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
# Artifact_a.txt和Artifact_c.csv的内容遍历
|
||||
output_lines = []
|
||||
@ -1317,7 +1398,7 @@ class Data:
|
||||
self.df_Artifact_a.to_csv(Path(Config["Path"]["Save_a"]), header=False, index=False, sep='\n')
|
||||
df_Artifact_b.to_csv(Path(Config["Path"]["Save_b"]), header=False, index=False, sep='\n')
|
||||
self.df_Artifact_a.to_csv(Path(Config["Path"]["Save_c"]), index=False,
|
||||
encoding=ConfigParams.GBK_ENCODING)
|
||||
encoding=Params.GBK_ENCODING)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON[
|
||||
"Save_Exception"] + "\n" + format_exc())
|
||||
@ -1331,19 +1412,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
|
||||
super().__init__(canvas, parent)
|
||||
# 初始化画框工具栏
|
||||
self.action_Label_Artifact = QAction(Constants.ARTIFACT_LABEL_ACTION_LABEL, self)
|
||||
self.action_Label_Artifact.setFont(QFont(ConfigParams.FONT, 14))
|
||||
self.action_Label_Artifact.setFont(QFont(Params.FONT, 14))
|
||||
self.action_Label_Artifact.setCheckable(True)
|
||||
self.action_Label_Artifact.setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY))
|
||||
Params.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY))
|
||||
self.insertAction(self._actions['pan'], self.action_Label_Artifact)
|
||||
|
||||
self._actions['pan'].setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.ACTION_PAN_SHORTCUT_KEY))
|
||||
Params.ACTION_PAN_SHORTCUT_KEY))
|
||||
self._actions['zoom'].setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY))
|
||||
Params.ACTION_ZOOM_SHORTCUT_KEY))
|
||||
|
||||
# 用于存储事件连接ID
|
||||
self.cid_mouse_press = None
|
||||
|
||||
1128
func/Module_bcg_quality_label.py
Normal file
1128
func/Module_bcg_quality_label.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,8 +10,9 @@ from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
|
||||
from ui.MainWindow.MainWindow_cut_PSG import Ui_MainWindow_cut_PSG
|
||||
@ -62,9 +63,9 @@ class MainWindow_cut_PSG(QMainWindow):
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"InputFolder": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT / Path(str(self.sampID))),
|
||||
"SaveFolder": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Path(str(self.sampID))),
|
||||
"InputAlignInfo": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL / Path(str(self.sampID)))
|
||||
"InputFolder": str(Path(self.root_path) / Filename.PATH_PSG_TEXT / Path(str(self.sampID))),
|
||||
"SaveFolder": str(Path(self.root_path) / Filename.PATH_PSG_ALIGNED / Path(str(self.sampID))),
|
||||
"InputAlignInfo": str(Path(self.root_path) / Filename.PATH_LABEL / Path(str(self.sampID)))
|
||||
}
|
||||
})
|
||||
|
||||
@ -94,11 +95,11 @@ class MainWindow_cut_PSG(QMainWindow):
|
||||
ButtonState["Current"].update(ButtonState["Default"].copy())
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.CUT_PSG_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.CUT_PSG_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.CUT_PSG_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.CUT_PSG_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.CUT_PSG_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.CUT_PSG_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.CUT_PSG_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.CUT_PSG_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
|
||||
@ -231,9 +232,9 @@ class Data:
|
||||
return Result().success(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FINISHED)
|
||||
|
||||
def open_file(self):
|
||||
path = str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT / Path(str(self.sampID)))
|
||||
path = str(Path(self.root_path) / Filename.PATH_PSG_TEXT / Path(str(self.sampID)))
|
||||
for value in Config["ChannelInput"].values():
|
||||
result = PublicFunc.examine_file(path, value)
|
||||
result = PublicFunc.examine_file(path, value, Params.ENDSWITH_TXT)
|
||||
if not result.status:
|
||||
return result
|
||||
|
||||
@ -242,20 +243,20 @@ class Data:
|
||||
|
||||
Config["Path"]["InputAlignInfo"] = str(
|
||||
Path(Config["Path"]["InputAlignInfo"]) / Path(
|
||||
ConfigParams.PRECISELY_ALIGN_INFO + ConfigParams.ENDSWITH_TXT))
|
||||
Filename.PRECISELY_ALIGN_INFO + Params.ENDSWITH_TXT))
|
||||
|
||||
try:
|
||||
for key in Config["ChannelInput"].keys():
|
||||
self.raw[key] = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["ChannelInput"][key] + str(self.freq[key]) + Config["EndWith"][key])),
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.SALabel = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["LabelInput"]["SA Label"] + Config["EndWith"]["SA Label"])),
|
||||
encoding=ConfigParams.GBK_ENCODING)
|
||||
encoding=Params.GBK_ENCODING)
|
||||
self.startTime = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["StartTime"] + Config["EndWith"]["StartTime"])),
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.alignInfo = read_csv(Path(Config["Path"]["InputAlignInfo"]),
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.alignInfo = literal_eval(self.alignInfo[0])
|
||||
except Exception as e:
|
||||
@ -290,7 +291,7 @@ class Data:
|
||||
try:
|
||||
# 读取SA标签
|
||||
self.SALabel = self.SALabel.loc[:, ~self.SALabel.columns.str.contains("^Unnamed")]
|
||||
self.SALabel = self.SALabel[self.SALabel["Event type"].isin(ConfigParams.CUT_PSG_SALABEL_EVENT)]
|
||||
self.SALabel = self.SALabel[self.SALabel["Event type"].isin(Params.CUT_PSG_SALABEL_EVENT)]
|
||||
self.SALabel["Duration"] = self.SALabel["Duration"].astype(str)
|
||||
self.SALabel["Duration"] = self.SALabel["Duration"].str.replace(r' \(.*?\)', '', regex=True)
|
||||
except Exception:
|
||||
@ -322,9 +323,6 @@ class Data:
|
||||
return Result().success(info=Constants.CUT_PSG_ALIGN_LABEL_FINISHED)
|
||||
|
||||
def save(self):
|
||||
if (not Path(Config["Path"]["SaveFolder"]).exists()) or (not Path(Config["Path"]["SaveFolder"]).is_dir()):
|
||||
Path(Config["Path"]["SaveFolder"]).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for raw in self.raw.values():
|
||||
if len(raw) == 0:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE +
|
||||
|
||||
@ -11,8 +11,9 @@ from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
from func.utils.detect_Jpeak import preprocess, Jpeak_Detection
|
||||
|
||||
@ -59,20 +60,20 @@ class SettingWindow(QMainWindow):
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.DETECT_JPEAK_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.DETECT_JPEAK_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.DETECT_JPEAK_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.DETECT_JPEAK_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Input": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Save": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID))))
|
||||
}
|
||||
})
|
||||
@ -94,7 +95,7 @@ class SettingWindow(QMainWindow):
|
||||
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
|
||||
self.config["ModelFolderPath"] = self.ui.plainTextEdit_deepmodel_path.toPlainText()
|
||||
|
||||
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
with open(Params.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
@ -105,18 +106,18 @@ class SettingWindow(QMainWindow):
|
||||
def __update_ui__(self):
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.BCG_FILTER +
|
||||
Path(Filename.BCG_FILTER +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.JPEAK_REVISE +
|
||||
Path(Filename.JPEAK_REVISE +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
|
||||
|
||||
class MainWindow_detect_Jpeak(QMainWindow):
|
||||
@ -169,7 +170,7 @@ class MainWindow_detect_Jpeak(QMainWindow):
|
||||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||||
|
||||
@ -204,7 +205,8 @@ class MainWindow_detect_Jpeak(QMainWindow):
|
||||
QApplication.processEvents()
|
||||
|
||||
# 清空画框
|
||||
self.ax0.clear()
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
@ -354,7 +356,7 @@ class MainWindow_detect_Jpeak(QMainWindow):
|
||||
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.peak.reshape(-1)))
|
||||
chunk_size = ConfigParams.DETECT_JPEAK_SAVE_CHUNK_SIZE
|
||||
chunk_size = Params.DETECT_JPEAK_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
@ -378,7 +380,7 @@ class MainWindow_detect_Jpeak(QMainWindow):
|
||||
def reset_axes(self):
|
||||
self.ax0.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
def update_ui_comboBox_model(self, model_list):
|
||||
self.ui.comboBox_model.clear()
|
||||
@ -397,21 +399,18 @@ class Data:
|
||||
if Path(Config["Path"]["Input"]).is_file():
|
||||
Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent)
|
||||
|
||||
if not Path(Config["Path"]["Input"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input"], ConfigParams.BCG_FILTER)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input"], Filename.BCG_FILTER, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input"] = result.data["path"]
|
||||
Config["InputConfig"]["Freq"] = result.data["freq"]
|
||||
Config["Path"]["Save"] = str(
|
||||
Path(Config["Path"]["Save"]) / Path(ConfigParams.JPEAK_REVISE + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
Path(Config["Path"]["Save"]) / Path(Filename.JPEAK_REVISE + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
|
||||
else:
|
||||
return result
|
||||
|
||||
try:
|
||||
self.raw_data = read_csv(Config["Path"]["Input"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
@ -461,9 +460,6 @@ class Data:
|
||||
return Result().success(info=Constants.DETECT_JPEAK_PREDICT_FINISHED)
|
||||
|
||||
def save(self, chunk):
|
||||
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if self.peak is None:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
|
||||
|
||||
@ -11,8 +11,9 @@ from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
from func.utils.detect_Rpeak import preprocess, Rpeak_Detection, get_method
|
||||
|
||||
@ -59,20 +60,20 @@ class SettingWindow(QMainWindow):
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.DETECT_RPEAK_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.DETECT_RPEAK_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.DETECT_RPEAK_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.DETECT_RPEAK_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Input": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Save": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID))))
|
||||
}
|
||||
})
|
||||
@ -91,7 +92,7 @@ class SettingWindow(QMainWindow):
|
||||
# 保存配置到文件
|
||||
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
|
||||
|
||||
with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
with open(Params.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
@ -102,18 +103,18 @@ class SettingWindow(QMainWindow):
|
||||
def __update_ui__(self):
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ECG_FILTER +
|
||||
Path(Filename.ECG_FILTER +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.RPEAK_FINAL +
|
||||
Path(Filename.RPEAK_FINAL +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
|
||||
|
||||
class MainWindow_detect_Rpeak(QMainWindow):
|
||||
@ -166,11 +167,11 @@ class MainWindow_detect_Rpeak(QMainWindow):
|
||||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||||
|
||||
@ -197,8 +198,10 @@ class MainWindow_detect_Rpeak(QMainWindow):
|
||||
QApplication.processEvents()
|
||||
|
||||
# 清空画框
|
||||
self.ax0.clear()
|
||||
self.ax1.clear()
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
if self.ax1 is not None:
|
||||
self.ax1.clear()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
@ -349,7 +352,7 @@ class MainWindow_detect_Rpeak(QMainWindow):
|
||||
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.peak.reshape(-1)))
|
||||
chunk_size = ConfigParams.DETECT_RPEAK_SAVE_CHUNK_SIZE
|
||||
chunk_size = Params.DETECT_RPEAK_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
@ -374,10 +377,10 @@ class MainWindow_detect_Rpeak(QMainWindow):
|
||||
self.ax0.clear()
|
||||
self.ax1.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
def update_ui_comboBox_method(self, method_list):
|
||||
self.ui.comboBox_method.clear()
|
||||
@ -397,21 +400,18 @@ class Data:
|
||||
if Path(Config["Path"]["Input"]).is_file():
|
||||
Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent)
|
||||
|
||||
if not Path(Config["Path"]["Input"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input"], ConfigParams.ECG_FILTER)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input"], Filename.ECG_FILTER, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input"] = result.data["path"]
|
||||
Config["InputConfig"]["Freq"] = result.data["freq"]
|
||||
Config["Path"]["Save"] = str(
|
||||
Path(Config["Path"]["Save"]) / Path(ConfigParams.RPEAK_FINAL + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
Path(Config["Path"]["Save"]) / Path(Filename.RPEAK_FINAL + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
|
||||
else:
|
||||
return result
|
||||
|
||||
try:
|
||||
self.raw_data = read_csv(Config["Path"]["Input"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
@ -452,9 +452,6 @@ class Data:
|
||||
return Result().success(info=Constants.DETECT_RPEAK_PREDICT_FINISHED)
|
||||
|
||||
def save(self, chunk):
|
||||
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if self.peak is None:
|
||||
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
|
||||
@ -9,14 +9,15 @@ from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication, QTableWidg
|
||||
from matplotlib import gridspec, patches
|
||||
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
||||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
||||
from numpy import append, delete, arange
|
||||
from numpy import append, delete, arange, setdiff1d
|
||||
from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from scipy.signal import find_peaks
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.Filters.Preprocessing import data_preprocess_for_label_check
|
||||
from func.utils.Result import Result
|
||||
|
||||
@ -34,16 +35,14 @@ ButtonState = {
|
||||
"pushButton_input": True,
|
||||
"pushButton_prev_move": False,
|
||||
"pushButton_pause": False,
|
||||
"pushButton_next_move": False,
|
||||
"pushButton_save": False
|
||||
"pushButton_next_move": False
|
||||
},
|
||||
"Current": {
|
||||
"pushButton_input_setting": True,
|
||||
"pushButton_input": True,
|
||||
"pushButton_prev_move": False,
|
||||
"pushButton_pause": False,
|
||||
"pushButton_next_move": False,
|
||||
"pushButton_save": False
|
||||
"pushButton_next_move": False
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,11 +70,11 @@ class SettingWindow(QMainWindow):
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.LABEL_CHECK_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.LABEL_CHECK_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.LABEL_CHECK_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.LABEL_CHECK_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
@ -83,13 +82,13 @@ class SettingWindow(QMainWindow):
|
||||
if self.mode == "BCG":
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input_Signal": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Peak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Approximately_Align": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
"Input_Signal": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Peak": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Approximately_Align": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Save": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID))))
|
||||
},
|
||||
"Mode": self.mode
|
||||
@ -97,13 +96,13 @@ class SettingWindow(QMainWindow):
|
||||
elif self.mode == "ECG":
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input_Signal": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Peak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Approximately_Align": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
"Input_Signal": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Peak": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Approximately_Align": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Save": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID))))
|
||||
},
|
||||
"Mode": self.mode
|
||||
@ -149,7 +148,7 @@ class SettingWindow(QMainWindow):
|
||||
# 保存配置到文件
|
||||
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq_signal.value()
|
||||
|
||||
with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
|
||||
with open(Params.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
@ -161,47 +160,47 @@ class SettingWindow(QMainWindow):
|
||||
if self.mode == "BCG":
|
||||
self.ui.plainTextEdit_file_path_input_signal.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.BCG_FILTER +
|
||||
Path(Filename.BCG_FILTER +
|
||||
str(self.ui.spinBox_input_freq_signal.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_peak.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.JPEAK_REVISE +
|
||||
Path(Filename.JPEAK_REVISE +
|
||||
str(self.ui.spinBox_input_freq_signal.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.JPEAK_REVISE_CORRECTED +
|
||||
Path(Filename.JPEAK_REVISE_CORRECTED +
|
||||
str(self.ui.spinBox_input_freq_signal.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
elif self.mode == "ECG":
|
||||
self.ui.plainTextEdit_file_path_input_signal.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ECG_FILTER +
|
||||
Path(Filename.ECG_FILTER +
|
||||
str(self.ui.spinBox_input_freq_signal.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_peak.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.RPEAK_FINAL +
|
||||
Path(Filename.RPEAK_FINAL +
|
||||
str(self.ui.spinBox_input_freq_signal.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.RPEAK_FINAL_CORRECTED +
|
||||
Path(Filename.RPEAK_FINAL_CORRECTED +
|
||||
str(self.ui.spinBox_input_freq_signal.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
else:
|
||||
raise ValueError("模式不存在")
|
||||
|
||||
@ -283,11 +282,11 @@ class MainWindow_label_check(QMainWindow):
|
||||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0, sharey=self.ax0)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||||
|
||||
@ -307,7 +306,6 @@ class MainWindow_label_check(QMainWindow):
|
||||
|
||||
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
|
||||
self.ui.pushButton_input_setting.clicked.connect(self.setting.show)
|
||||
self.ui.pushButton_save.clicked.connect(self.__slot_btn_save__)
|
||||
self.ui.pushButton_prev_move.clicked.connect(self.__slot_btn_move__)
|
||||
self.ui.pushButton_pause.clicked.connect(self.__slot_btn_move__)
|
||||
self.ui.pushButton_next_move.clicked.connect(self.__slot_btn_move__)
|
||||
@ -340,8 +338,10 @@ class MainWindow_label_check(QMainWindow):
|
||||
del self.point_peak_original
|
||||
del self.point_peak_corrected
|
||||
del self.annotation_tableWidget
|
||||
self.ax0.clear()
|
||||
self.ax1.clear()
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
if self.ax1 is not None:
|
||||
self.ax1.clear()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
@ -464,70 +464,81 @@ class MainWindow_label_check(QMainWindow):
|
||||
self.data = Data()
|
||||
|
||||
# 导入数据
|
||||
PublicFunc.progressbar_update(self, 1, 6, Constants.INPUTTING_DATA, 0)
|
||||
PublicFunc.progressbar_update(self, 1, 7, Constants.INPUTTING_DATA, 0)
|
||||
result = self.data.open_file()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(1/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.text_output(self.ui, "(1/7)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(1/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, "(1/7)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
# 获取存档
|
||||
PublicFunc.progressbar_update(self, 2, 6, Constants.LOADING_ARCHIVE, 20)
|
||||
PublicFunc.progressbar_update(self, 2, 7, Constants.LOADING_ARCHIVE, 20)
|
||||
result = self.data.get_archive()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.text_output(self.ui, "(2/7)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, "(2/7)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
# 保存
|
||||
PublicFunc.progressbar_update(self, 3, 7, Constants.SAVING_DATA, 25)
|
||||
result = self.data.save()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(3/7)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(3/7)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
# 数据预处理
|
||||
PublicFunc.progressbar_update(self, 3, 6, Constants.PREPROCESSING_DATA, 30)
|
||||
PublicFunc.progressbar_update(self, 4, 7, Constants.PREPROCESSING_DATA, 30)
|
||||
result = self.data.preprocess()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(3/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.text_output(self.ui, "(4/7)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(3/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, "(4/7)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
# 更新表格
|
||||
PublicFunc.progressbar_update(self, 4, 6, Constants.UPDATING_TABLEWIDGET_AND_INFO, 50)
|
||||
PublicFunc.progressbar_update(self, 5, 7, Constants.UPDATING_TABLEWIDGET_AND_INFO, 50)
|
||||
result = self.__update_tableWidget_and_info__()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(4/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.text_output(self.ui, "(5/7)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(4/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, "(5/7)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
# 绘图
|
||||
PublicFunc.progressbar_update(self, 5, 6, Constants.DRAWING_DATA, 60)
|
||||
PublicFunc.progressbar_update(self, 6, 7, Constants.DRAWING_DATA, 60)
|
||||
result = self.__plot__()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(5/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.text_output(self.ui, "(6/7)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(5/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, "(6/7)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
# 绘点
|
||||
PublicFunc.progressbar_update(self, 6, 6, Constants.DRAWING_DATA, 80)
|
||||
PublicFunc.progressbar_update(self, 7, 7, Constants.DRAWING_DATA, 80)
|
||||
result = self.__plot_peaks__()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(6/6)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.text_output(self.ui, "(7/7)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(6/6)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, "(7/7)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
self.__reset__()
|
||||
self.canvas.mpl_connect("motion_notify_event", self.on_motion)
|
||||
@ -539,42 +550,8 @@ class MainWindow_label_check(QMainWindow):
|
||||
ButtonState["Current"]["pushButton_prev_move"] = True
|
||||
ButtonState["Current"]["pushButton_next_move"] = True
|
||||
ButtonState["Current"]["pushButton_pause"] = True
|
||||
ButtonState["Current"]["pushButton_save"] = True
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
def __slot_btn_save__(self):
|
||||
reply = QMessageBox.question(self, Constants.QUESTION_TITLE,
|
||||
Constants.QUESTION_CONTENT + Config["Path"]["Save"],
|
||||
QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.Yes)
|
||||
if reply == QMessageBox.Yes:
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
|
||||
# 保存
|
||||
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.corrected_peak.reshape(-1)))
|
||||
chunk_size = ConfigParams.LABEL_CHECK_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
chunk = DataFrame(self.data.corrected_peak.reshape(-1)).iloc[start:end]
|
||||
result = self.data.save(chunk)
|
||||
progress = int((end / total_rows) * 100)
|
||||
self.progressbar.setValue(progress)
|
||||
QApplication.processEvents()
|
||||
|
||||
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)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
def __slot_btn_move__(self):
|
||||
if self.data is None:
|
||||
return
|
||||
@ -670,13 +647,15 @@ class MainWindow_label_check(QMainWindow):
|
||||
PublicFunc.text_output(self.ui, f"{Constants.LABEL_CHECK_JUMP_X_INDEX}{str(int(x))}", Constants.TIPS_TYPE_INFO)
|
||||
|
||||
def reset_axes(self):
|
||||
self.ax0.clear()
|
||||
self.ax1.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
|
||||
if self.ax1 is not None:
|
||||
self.ax1.clear()
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
def on_xlim_change(self, event_ax):
|
||||
try:
|
||||
@ -814,6 +793,7 @@ class MainWindow_label_check(QMainWindow):
|
||||
height=Config["FindPeaks"]["MinHeight"],
|
||||
distance=Config["FindPeaks"]["MinInterval"])
|
||||
peaks_idx = peaks_idx + int(rect_left)
|
||||
peaks_idx = setdiff1d(peaks_idx, self.data.corrected_peak)
|
||||
if len(peaks_idx) != 0:
|
||||
PublicFunc.text_output(self.ui, f"{Constants.LABEL_CHECK_ADD_POINTS_SUCCESSFULLY}{peaks_idx}",
|
||||
Constants.TIPS_TYPE_INFO)
|
||||
@ -843,7 +823,14 @@ class MainWindow_label_check(QMainWindow):
|
||||
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__()
|
||||
DataFrame(self.data.corrected_peak).to_csv(Config["Path"]["Save"], index=False, header=False)
|
||||
result = self.data.save()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, result.info, Constants.TIPS_TYPE_INFO)
|
||||
# 移除矩形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()
|
||||
@ -860,24 +847,24 @@ class MainWindow_label_check(QMainWindow):
|
||||
if self.figToolbar.rect_patch_ax0 is None:
|
||||
if self.is_left_button_pressed:
|
||||
self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True,
|
||||
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
elif self.is_right_button_pressed:
|
||||
self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True,
|
||||
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_RED)
|
||||
alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_RED)
|
||||
self.ax0.add_patch(self.figToolbar.rect_patch_ax0)
|
||||
|
||||
# 如果矩形patch不存在,则创建一个新的
|
||||
if self.figToolbar.rect_patch_ax1 is None:
|
||||
if self.is_left_button_pressed:
|
||||
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
|
||||
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
elif self.is_right_button_pressed:
|
||||
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
|
||||
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_RED)
|
||||
alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_RED)
|
||||
self.ax1.add_patch(self.figToolbar.rect_patch_ax1)
|
||||
|
||||
# 更新矩形patch的位置和大小
|
||||
@ -908,13 +895,13 @@ class Data:
|
||||
|
||||
def open_file(self):
|
||||
if Config["Mode"] == "BCG":
|
||||
signal = ConfigParams.BCG_FILTER
|
||||
peak = ConfigParams.JPEAK_REVISE
|
||||
save = ConfigParams.JPEAK_REVISE_CORRECTED
|
||||
signal = Filename.BCG_FILTER
|
||||
peak = Filename.JPEAK_REVISE
|
||||
save = Filename.JPEAK_REVISE_CORRECTED
|
||||
elif Config["Mode"] == "ECG":
|
||||
signal = ConfigParams.ECG_FILTER
|
||||
peak = ConfigParams.RPEAK_FINAL
|
||||
save = ConfigParams.RPEAK_FINAL_CORRECTED
|
||||
signal = Filename.ECG_FILTER
|
||||
peak = Filename.RPEAK_FINAL
|
||||
save = Filename.RPEAK_FINAL_CORRECTED
|
||||
else:
|
||||
raise ValueError("模式不存在")
|
||||
if Path(Config["Path"]["Input_Signal"]).is_file():
|
||||
@ -926,28 +913,38 @@ class Data:
|
||||
if Path(Config["Path"]["Save"]).is_file():
|
||||
Config["Path"]["Save"] = str(Path(Config["Path"]["Save"]).parent)
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Signal"], signal)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_Signal"], signal, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_Signal"] = result.data["path"]
|
||||
Config["Path"]["Input_Peak"] = str(
|
||||
Path(Config["Path"]["Input_Peak"]) / Path(peak + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
Config["InputConfig"]["Freq"] = result.data["freq"]
|
||||
Config["Path"]["Input_Approximately_Align"] = str(
|
||||
Path(Config["Path"]["Input_Approximately_Align"]) / Path(ConfigParams.APPROXIMATELY_ALIGN_INFO + ConfigParams.ENDSWITH_CSV))
|
||||
Config["Path"]["Save"] = str(
|
||||
Path(Config["Path"]["Save"]) / Path(save + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
else:
|
||||
return result
|
||||
|
||||
if (not Path(Config["Path"]["Input_Signal"]).exists()) or (not Path(Config["Path"]["Input_Peak"]).exists()):
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
Config["Path"]["Input_Peak"] = str(
|
||||
Path(Config["Path"]["Input_Peak"]) / Path(peak + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Input_Approximately_Align"] = str(
|
||||
Path(Config["Path"]["Input_Approximately_Align"]) / Path(
|
||||
Filename.APPROXIMATELY_ALIGN_INFO + Params.ENDSWITH_CSV))
|
||||
Config["Path"]["Save"] = str(
|
||||
Path(Config["Path"]["Save"]) / Path(save + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
|
||||
|
||||
if not Path(Config["Path"]["Input_Peak"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
peak + ":" +
|
||||
Config["Path"]["Input_Peak"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
Filename.APPROXIMATELY_ALIGN_INFO + ":" +
|
||||
Config["Path"]["Input_Approximately_Align"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
try:
|
||||
self.raw_data = read_csv(Config["Path"]["Input_Signal"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.original_peak = read_csv(Config["Path"]["Input_Peak"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
@ -979,7 +976,7 @@ class Data:
|
||||
return Result().success(info=Constants.ARCHIVE_NOT_EXIST)
|
||||
else:
|
||||
self.corrected_peak = read_csv(Config["Path"]["Save"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
return Result().success(info=Constants.ARCHIVE_EXIST)
|
||||
|
||||
@ -1010,15 +1007,12 @@ class Data:
|
||||
|
||||
return Result().success(info=Constants.PREPROCESS_FINISHED)
|
||||
|
||||
def save(self, chunk):
|
||||
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def save(self):
|
||||
if self.corrected_peak is None:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
|
||||
try:
|
||||
chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False)
|
||||
DataFrame(self.corrected_peak).to_csv(Config["Path"]["Save"], index=False, header=False)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE +
|
||||
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
|
||||
@ -1032,19 +1026,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
|
||||
super().__init__(canvas, parent)
|
||||
# 初始化画框工具栏
|
||||
self.action_Label_Multiple = QAction(Constants.LABEL_CHECK_ACTION_LABEL_MULTIPLE_NAME, self)
|
||||
self.action_Label_Multiple.setFont(QFont(ConfigParams.FONT, 14))
|
||||
self.action_Label_Multiple.setFont(QFont(Params.FONT, 14))
|
||||
self.action_Label_Multiple.setCheckable(True)
|
||||
self.action_Label_Multiple.setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY))
|
||||
Params.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY))
|
||||
self.insertAction(self._actions['pan'], self.action_Label_Multiple)
|
||||
|
||||
self._actions['pan'].setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.ACTION_PAN_SHORTCUT_KEY))
|
||||
Params.ACTION_PAN_SHORTCUT_KEY))
|
||||
self._actions['zoom'].setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY))
|
||||
Params.ACTION_ZOOM_SHORTCUT_KEY))
|
||||
|
||||
# 用于存储事件连接ID
|
||||
self.cid_mouse_press = None
|
||||
|
||||
@ -16,9 +16,12 @@ from func.Module_label_check import MainWindow_label_check
|
||||
from func.Module_precisely_align import MainWindow_precisely_align
|
||||
from func.Module_cut_PSG import MainWindow_cut_PSG
|
||||
from func.Module_artifact_label import MainWindow_artifact_label
|
||||
from func.Module_bcg_quality_label import MainWindow_bcg_quality_label
|
||||
from func.Module_resp_quality_label import MainWindow_resp_quality_label
|
||||
from func.Module_SA_label import MainWindow_SA_label
|
||||
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.Constants import Constants
|
||||
|
||||
|
||||
use("QtAgg")
|
||||
@ -52,7 +55,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
|
||||
self.__read_config__()
|
||||
self.ui.plainTextEdit_root_path.setPlainText(Config["Path"]["Root"])
|
||||
self.seek_sampID(Path(Config["Path"]["Root"]) / Path(ConfigParams.PUBLIC_PATH_ORGBCG_TEXT))
|
||||
self.seek_sampID(Path(Config["Path"]["Root"]) / Path(Filename.PATH_ORGBCG_TEXT))
|
||||
|
||||
self.approximately_align = None
|
||||
self.preprocess = None
|
||||
@ -62,7 +65,8 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.precisely_align = None
|
||||
self.cut_PSG = None
|
||||
self.artifact_label = None
|
||||
|
||||
self.bcg_quality_label = None
|
||||
self.resp_quality_label = None
|
||||
self.SA_label = None
|
||||
|
||||
# 绑定槽函数
|
||||
@ -77,22 +81,24 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.ui.pushButton_precisely_align.clicked.connect(self.__slot_btn_precisely_align__)
|
||||
self.ui.pushButton_cut_PSG.clicked.connect(self.__slot_btn_cut_PSG__)
|
||||
self.ui.pushButton_artifact_label.clicked.connect(self.__slot_btn_artifact_label__)
|
||||
self.ui.pushButton_bcg_quality_label.clicked.connect(self.__slot_btn_bcg_quality_label__)
|
||||
self.ui.pushButton_resp_quality_label.clicked.connect(self.__slot_btn_resp_quality_label__)
|
||||
self.ui.pushButton_SA_label.clicked.connect(self.__slot_btn_SA_label__)
|
||||
|
||||
@staticmethod
|
||||
def __read_config__():
|
||||
if not Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).exists():
|
||||
Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.PUBLIC_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.PUBLIC_CONFIG_FILE_PATH).exists():
|
||||
Path(Params.PUBLIC_CONFIG_FILE_PATH).parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(Params.PUBLIC_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.PUBLIC_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.PUBLIC_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
|
||||
@staticmethod
|
||||
def __write_config__():
|
||||
with open(Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH), "w") as f:
|
||||
with open(Path(Params.PUBLIC_CONFIG_FILE_PATH), "w") as f:
|
||||
dump(Config, f)
|
||||
|
||||
def __slot_btn_open__(self):
|
||||
@ -100,7 +106,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
file_dialog.setFileMode(QFileDialog.Directory)
|
||||
file_dialog.setOption(QFileDialog.ShowDirsOnly, True)
|
||||
if file_dialog.exec_() == QFileDialog.Accepted:
|
||||
self.seek_sampID(Path(file_dialog.selectedFiles()[0]) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT)
|
||||
self.seek_sampID(Path(file_dialog.selectedFiles()[0]) / Filename.PATH_ORGBCG_TEXT)
|
||||
self.ui.plainTextEdit_root_path.setPlainText(file_dialog.selectedFiles()[0])
|
||||
|
||||
# 修改配置
|
||||
@ -120,6 +126,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.approximately_align.show(root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.approximately_align.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_preprocess__(self):
|
||||
self.preprocess = MainWindow_preprocess()
|
||||
@ -140,6 +147,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.preprocess.show(mode, root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.preprocess.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_detect_Jpeak__(self):
|
||||
self.detect_Jpeak = MainWindow_detect_Jpeak()
|
||||
@ -152,6 +160,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.detect_Jpeak.show(root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.detect_Jpeak.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_detect_Rpeak__(self):
|
||||
self.detect_Rpeak = MainWindow_detect_Rpeak()
|
||||
@ -164,6 +173,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.detect_Rpeak.show(root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.detect_Rpeak.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_label_check__(self):
|
||||
self.label_check = MainWindow_label_check()
|
||||
@ -186,7 +196,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.label_check.show(mode, root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.label_check.showMaximized()
|
||||
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_precisely_align__(self):
|
||||
self.precisely_align = MainWindow_precisely_align()
|
||||
@ -199,6 +209,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.precisely_align.show(root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.precisely_align.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_cut_PSG__(self):
|
||||
self.cut_PSG = MainWindow_cut_PSG()
|
||||
@ -209,6 +220,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.cut_PSG.show(root_path, int(sampID))
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_artifact_label__(self):
|
||||
self.artifact_label = MainWindow_artifact_label()
|
||||
@ -221,6 +233,33 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.artifact_label.show(root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.artifact_label.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_bcg_quality_label__(self):
|
||||
self.bcg_quality_label = MainWindow_bcg_quality_label()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.bcg_quality_label.show(root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.bcg_quality_label.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_resp_quality_label__(self):
|
||||
self.resp_quality_label = MainWindow_resp_quality_label()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.resp_quality_label.show(root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.resp_quality_label.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_SA_label__(self):
|
||||
self.SA_label = MainWindow_SA_label()
|
||||
@ -233,6 +272,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.SA_label.show(root_path, int(sampID))
|
||||
# 默认最大化显示而非固定分辨率
|
||||
self.SA_label.showMaximized()
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def seek_sampID(self, path):
|
||||
if not Path(path).exists():
|
||||
@ -242,7 +282,6 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
sub_folders = [item.name for item in Path(path).iterdir() if item.is_dir()]
|
||||
self.ui.comboBox_sampID.addItems(sub_folders)
|
||||
|
||||
|
||||
def check_root_path(self):
|
||||
if self.ui.plainTextEdit_root_path.toPlainText() == Constants.STRING_IS_EMPTY:
|
||||
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR)
|
||||
@ -254,3 +293,16 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_SAMPID_EMPTY, Constants.MSGBOX_TYPE_ERROR)
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_save_path_and_mkdir(self, root_path, sampID):
|
||||
path_Label = Path(root_path) / Path(Filename.PATH_LABEL) / Path(str(sampID))
|
||||
path_OrgBCG_Aligned = Path(root_path) / Path(Filename.PATH_ORGBCG_ALIGNED) / Path(str(sampID))
|
||||
path_PSG_Aligned = Path(root_path) / Path(Filename.PATH_PSG_ALIGNED) / Path(str(sampID))
|
||||
path_OrgBCG_Text = Path(root_path) / Path(Filename.PATH_ORGBCG_TEXT) / Path(str(sampID))
|
||||
path_PSG_Text = Path(root_path) / Path(Filename.PATH_PSG_TEXT) / Path(str(sampID))
|
||||
|
||||
path_list = [path_Label, path_OrgBCG_Aligned, path_PSG_Aligned, path_OrgBCG_Text, path_PSG_Text]
|
||||
|
||||
for path in path_list:
|
||||
if not path.exists():
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
@ -17,8 +17,9 @@ from resampy import resample
|
||||
from scipy.signal import find_peaks
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
|
||||
from ui.MainWindow.MainWindow_precisely_align import Ui_MainWindow_precisely_align
|
||||
@ -102,40 +103,40 @@ class SettingWindow(QMainWindow):
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.PRECISELY_ALIGN_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.PRECISELY_ALIGN_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input_OrgBCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Input_OrgBCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Input_BCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Jpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Input_Jpeak": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_ECG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Input_ECG": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Rpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Input_Rpeak": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Input_Approximately_Align": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Input_Approximately_Align": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_AlignInfo": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_OrgBCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
"Save_AlignInfo": str((Path(self.root_path) / Filename.PATH_LABEL /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_OrgBCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
"Save_BCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_ECG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
"Save_ECG": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_Jpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_Rpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
"Save_Jpeak": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)))),
|
||||
"Save_Rpeak": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID))))
|
||||
},
|
||||
"Coordinate": {
|
||||
@ -221,7 +222,7 @@ class SettingWindow(QMainWindow):
|
||||
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.value()
|
||||
self.config["InputConfig"]["ECGFreq"] = self.ui.spinBox_input_freq_ECG.value()
|
||||
|
||||
with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
|
||||
with open(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
@ -232,60 +233,60 @@ class SettingWindow(QMainWindow):
|
||||
def __update_ui__(self):
|
||||
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ORGBCG_RAW +
|
||||
Path(Filename.ORGBCG_RAW +
|
||||
str(self.ui.spinBox_input_freq_orgBcg.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_BCG.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.BCG_FILTER +
|
||||
Path(Filename.BCG_FILTER +
|
||||
str(self.ui.spinBox_input_freq_BCG.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_input_ECG.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ECG_FILTER +
|
||||
Path(Filename.ECG_FILTER +
|
||||
str(self.ui.spinBox_input_freq_ECG.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save_orgBcg.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ORGBCG_SYNC +
|
||||
Path(Filename.ORGBCG_SYNC +
|
||||
str(self.ui.spinBox_input_freq_orgBcg.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save_BCG.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.BCG_SYNC +
|
||||
Path(Filename.BCG_SYNC +
|
||||
str(self.ui.spinBox_input_freq_BCG.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save_ECG.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ECG_SYNC +
|
||||
Path(Filename.ECG_SYNC +
|
||||
str(self.ui.spinBox_input_freq_ECG.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save_Jpeak.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
|
||||
Filename.PATH_ORGBCG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.JPEAK_SYNC +
|
||||
Path(Filename.JPEAK_SYNC +
|
||||
str(self.ui.spinBox_input_freq_BCG.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save_Rpeak.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
|
||||
Filename.PATH_PSG_ALIGNED /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.RPEAK_SYNC +
|
||||
Path(Filename.RPEAK_SYNC +
|
||||
str(self.ui.spinBox_input_freq_ECG.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
|
||||
|
||||
class MainWindow_precisely_align(QMainWindow):
|
||||
@ -463,10 +464,10 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
self.fig.subplots_adjust(top=0.95, bottom=0.05, right=0.98, left=0.05, hspace=0.15, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0, sharey=self.ax0)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
Jpeak = self.data.Jpeak[:-2]
|
||||
Rpeak = self.data.Rpeak[:-2]
|
||||
@ -500,16 +501,16 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
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])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax1 = self.fig.add_subplot(self.gs[2])
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax2 = self.fig.add_subplot(self.gs[1])
|
||||
self.ax2.grid(True)
|
||||
self.ax2.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax3 = self.fig.add_subplot(self.gs[3])
|
||||
self.ax3.grid(True)
|
||||
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
self.ax0.set_title(
|
||||
"front\ncorre_IIV: {}, corre_II: {}\nsame_sign_rate:{}, total_time_ratio: {}\nshift: {}, alignment offset: {} seconds\noffset_interval: {}, anchor_J: {}, anchor_R: {}".format(
|
||||
@ -566,7 +567,7 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
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])
|
||||
self.ax4.grid(True)
|
||||
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
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)
|
||||
@ -587,7 +588,7 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
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])
|
||||
self.ax4.grid(True)
|
||||
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
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)
|
||||
@ -687,7 +688,7 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
def __slot_btn_calculate_correlation__(self, test1=None, shift_front=None, shift_back=None):
|
||||
# TODO:这里有个未知的问BUG,虽然不影响功能,但会影响代码整洁性,第一个形参赋值为None时,之后使用变量时将会变成False,不知道为什么
|
||||
# TODO:这里有个未知的BUG,虽然不影响功能,但会影响代码整洁性,第一个形参赋值为None时,之后使用变量时将会变成False,不知道为什么
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
|
||||
sender = self.sender()
|
||||
@ -839,7 +840,7 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
PublicFunc.progressbar_update(self, 2, 6, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.res_orgBcg.reshape(-1)))
|
||||
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
|
||||
chunk_size = Params.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save_OrgBCG"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
@ -861,7 +862,7 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
PublicFunc.progressbar_update(self, 3, 6, Constants.PRECISELY_ALIGN_SAVING_RES_BCG, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.res_BCG.reshape(-1)))
|
||||
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
|
||||
chunk_size = Params.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save_BCG"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
@ -883,7 +884,7 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
PublicFunc.progressbar_update(self, 4, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.cut_ECG.reshape(-1)))
|
||||
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
|
||||
chunk_size = Params.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save_ECG"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
@ -905,7 +906,7 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
PublicFunc.progressbar_update(self, 5, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.cut_Jpeak.reshape(-1)))
|
||||
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
|
||||
chunk_size = Params.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save_Jpeak"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
@ -927,7 +928,7 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
PublicFunc.progressbar_update(self, 6, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.cut_Rpeak.reshape(-1)))
|
||||
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
|
||||
chunk_size = Params.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save_Rpeak"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
@ -1014,23 +1015,23 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
if self.ax1 is not None:
|
||||
self.ax1.clear()
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
if self.ax2 is not None:
|
||||
self.ax2.clear()
|
||||
self.ax2.grid(True)
|
||||
self.ax2.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
if self.ax3 is not None:
|
||||
self.ax3.clear()
|
||||
self.ax3.grid(True)
|
||||
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
if self.ax4 is not None:
|
||||
self.ax4.clear()
|
||||
self.ax4.grid(True)
|
||||
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
def redraw_calculate_coordination(self, plot_element=None):
|
||||
if plot_element is not None and plot_element["mode"] == "select":
|
||||
@ -1327,26 +1328,26 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
if self.figToolbar.ax0_BCG_rectangle_front is None and self.is_left_button_pressed:
|
||||
self.figToolbar.ax0_BCG_rectangle_front = patches.Rectangle((0, 0), 1, 1,
|
||||
fill=True,
|
||||
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
|
||||
alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
self.ax0.add_patch(self.figToolbar.ax0_BCG_rectangle_front)
|
||||
if self.figToolbar.ax0_BCG_rectangle_back is None and self.is_left_button_pressed:
|
||||
self.figToolbar.ax0_BCG_rectangle_back = patches.Rectangle((0, 0), 1, 1,
|
||||
fill=True,
|
||||
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
fill=True,
|
||||
alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
self.ax0.add_patch(self.figToolbar.ax0_BCG_rectangle_back)
|
||||
if self.figToolbar.ax1_ECG_rectangle_front is None and self.is_left_button_pressed:
|
||||
self.figToolbar.ax1_ECG_rectangle_front = patches.Rectangle((0, 0), 1, 1,
|
||||
fill=True,
|
||||
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
|
||||
alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
self.ax1.add_patch(self.figToolbar.ax1_ECG_rectangle_front)
|
||||
if self.figToolbar.ax1_ECG_rectangle_back is None and self.is_left_button_pressed:
|
||||
self.figToolbar.ax1_ECG_rectangle_back = patches.Rectangle((0, 0), 1, 1,
|
||||
fill=True,
|
||||
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
fill=True,
|
||||
alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
|
||||
color=Constants.PLOT_COLOR_PINK)
|
||||
self.ax1.add_patch(self.figToolbar.ax1_ECG_rectangle_back)
|
||||
|
||||
if self.ui.radioButton_BCG_front.isChecked():
|
||||
@ -1454,72 +1455,83 @@ class Data:
|
||||
if Path(Config["Path"]["Input_Approximately_Align"]).is_file():
|
||||
Config["Path"]["Input_Approximately_Align"] = str(Path(Config["Path"]["Input_Approximately_Align"]).parent)
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], ConfigParams.ORGBCG_RAW)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_RAW, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_OrgBCG"] = result.data["path"]
|
||||
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
|
||||
Config["Path"]["Input_Approximately_Align"] = str(
|
||||
Path(Config["Path"]["Input_Approximately_Align"]) / Path(
|
||||
ConfigParams.APPROXIMATELY_ALIGN_INFO + ConfigParams.ENDSWITH_CSV))
|
||||
Config["Path"]["Save_AlignInfo"] = str(
|
||||
Path(Config["Path"]["Save_AlignInfo"]) / Path(
|
||||
ConfigParams.PRECISELY_ALIGN_INFO + ConfigParams.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_OrgBCG"] = str(
|
||||
Path(Config["Path"]["Save_OrgBCG"]) / Path(
|
||||
ConfigParams.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], ConfigParams.BCG_FILTER)
|
||||
Config["Path"]["Input_Approximately_Align"] = str(
|
||||
Path(Config["Path"]["Input_Approximately_Align"]) / Path(
|
||||
Filename.APPROXIMATELY_ALIGN_INFO + Params.ENDSWITH_CSV))
|
||||
Config["Path"]["Save_AlignInfo"] = str(
|
||||
Path(Config["Path"]["Save_AlignInfo"]) / Path(
|
||||
Filename.PRECISELY_ALIGN_INFO + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_OrgBCG"] = str(
|
||||
Path(Config["Path"]["Save_OrgBCG"]) / Path(
|
||||
Filename.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + Params.ENDSWITH_TXT))
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_FILTER, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_BCG"] = result.data["path"]
|
||||
Config["InputConfig"]["BCGFreq"] = result.data["freq"]
|
||||
Config["Path"]["Input_Jpeak"] = str(
|
||||
Path(Config["Path"]["Input_Jpeak"]) / Path(ConfigParams.JPEAK_REVISE_CORRECTED + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_BCG"] = str(
|
||||
Path(Config["Path"]["Save_BCG"]) / Path(
|
||||
ConfigParams.BCG_SYNC + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_Jpeak"] = str(
|
||||
Path(Config["Path"]["Save_Jpeak"]) / Path(
|
||||
ConfigParams.JPEAK_SYNC + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
else:
|
||||
return result
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], ConfigParams.ECG_FILTER)
|
||||
Config["Path"]["Input_Jpeak"] = str(
|
||||
Path(Config["Path"]["Input_Jpeak"]) / Path(Filename.JPEAK_REVISE_CORRECTED + str(
|
||||
Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_BCG"] = str(
|
||||
Path(Config["Path"]["Save_BCG"]) / Path(
|
||||
Filename.BCG_SYNC + str(Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_Jpeak"] = str(
|
||||
Path(Config["Path"]["Save_Jpeak"]) / Path(
|
||||
Filename.JPEAK_SYNC + str(Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], Filename.ECG_FILTER, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_ECG"] = result.data["path"]
|
||||
Config["InputConfig"]["ECGFreq"] = result.data["freq"]
|
||||
Config["Path"]["Input_Rpeak"] = str(
|
||||
Path(Config["Path"]["Input_Rpeak"]) / Path(ConfigParams.RPEAK_FINAL_CORRECTED + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_ECG"] = str(
|
||||
Path(Config["Path"]["Save_ECG"]) / Path(
|
||||
ConfigParams.ECG_SYNC + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_Rpeak"] = str(
|
||||
Path(Config["Path"]["Save_Rpeak"]) / Path(
|
||||
ConfigParams.RPEAK_SYNC + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
else:
|
||||
return result
|
||||
Config["Path"]["Input_Rpeak"] = str(
|
||||
Path(Config["Path"]["Input_Rpeak"]) / Path(
|
||||
Filename.RPEAK_FINAL_CORRECTED + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_ECG"] = str(
|
||||
Path(Config["Path"]["Save_ECG"]) / Path(
|
||||
Filename.ECG_SYNC + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_Rpeak"] = str(
|
||||
Path(Config["Path"]["Save_Rpeak"]) / Path(
|
||||
Filename.RPEAK_SYNC + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
|
||||
|
||||
if ((not Path(Config["Path"]["Input_OrgBCG"]).exists())
|
||||
or (not Path(Config["Path"]["Input_BCG"]).exists())
|
||||
or (not Path(Config["Path"]["Input_Jpeak"]).exists())
|
||||
or (not Path(Config["Path"]["Input_ECG"]).exists())
|
||||
or (not Path(Config["Path"]["Input_Rpeak"]).exists())):
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
if not Path(Config["Path"]["Input_Jpeak"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
Filename.JPEAK_REVISE_CORRECTED + ":" +
|
||||
Config["Path"]["Input_Jpeak"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
if not Path(Config["Path"]["Input_Rpeak"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
Filename.RPEAK_FINAL_CORRECTED + ":" +
|
||||
Config["Path"]["Input_Rpeak"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
Filename.APPROXIMATELY_ALIGN_INFO + ":" +
|
||||
Config["Path"]["Input_Approximately_Align"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
try:
|
||||
self.raw_orgBcg = read_csv(Config["Path"]["Input_OrgBCG"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.raw_BCG = read_csv(Config["Path"]["Input_BCG"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.Jpeak = read_csv(Config["Path"]["Input_Jpeak"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.raw_ECG = read_csv(Config["Path"]["Input_ECG"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.Rpeak = read_csv(Config["Path"]["Input_Rpeak"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.argmax_BCG = np_argmax(self.raw_BCG)
|
||||
self.argmax_ECG = np_argmax(self.raw_ECG)
|
||||
@ -1536,6 +1548,7 @@ class Data:
|
||||
self.BCG_early = False
|
||||
elif self.approximately_align_pos < 0:
|
||||
self.BCG_early = True
|
||||
self.approximately_align_pos = - self.approximately_align_pos
|
||||
else:
|
||||
self.approximately_align_pos = 0
|
||||
self.BCG_early = None
|
||||
@ -1858,9 +1871,6 @@ class Data:
|
||||
return Result().success(info=info)
|
||||
|
||||
def save_alignInfo(self):
|
||||
if (not Path(Config["Path"]["Save_AlignInfo"]).parent.exists()) or (not Path(Config["Path"]["Save_AlignInfo"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save_AlignInfo"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
save_data = {
|
||||
"front": {
|
||||
@ -1992,19 +2002,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
|
||||
super().__init__(canvas, parent)
|
||||
# 初始化画框工具栏
|
||||
self.action_Get_Range = QAction(Constants.PRECISELY_ALIGN_ACTION_GET_RANGE_NAME, self)
|
||||
self.action_Get_Range.setFont(QFont(ConfigParams.FONT, 14))
|
||||
self.action_Get_Range.setFont(QFont(Params.FONT, 14))
|
||||
self.action_Get_Range.setCheckable(True)
|
||||
self.action_Get_Range.setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY))
|
||||
Params.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY))
|
||||
self.insertAction(self._actions['pan'], self.action_Get_Range)
|
||||
|
||||
self._actions['pan'].setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.ACTION_PAN_SHORTCUT_KEY))
|
||||
Params.ACTION_PAN_SHORTCUT_KEY))
|
||||
self._actions['zoom'].setShortcut(QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY))
|
||||
Params.ACTION_ZOOM_SHORTCUT_KEY))
|
||||
|
||||
# 用于存储事件连接ID
|
||||
self.cid_mouse_press = None
|
||||
|
||||
@ -12,8 +12,9 @@ from pandas import read_csv, DataFrame
|
||||
from scipy.signal import resample
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.Constants import Constants
|
||||
from func.Filters.Preprocessing import Butterworth_for_BCG_PreProcess, Butterworth_for_ECG_PreProcess
|
||||
from func.utils.Result import Result
|
||||
|
||||
@ -62,11 +63,11 @@ class SettingWindow(QMainWindow):
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(ConfigParams.PREPROCESS_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.PREPROCESS_CONFIG_NEW_CONTENT, f)
|
||||
if not Path(Params.PREPROCESS_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.PREPROCESS_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "r") as f:
|
||||
with open(Params.PREPROCESS_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
@ -74,9 +75,9 @@ class SettingWindow(QMainWindow):
|
||||
if self.mode == "BCG":
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Input": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
"Save": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID))))
|
||||
},
|
||||
"Mode": self.mode
|
||||
@ -84,9 +85,9 @@ class SettingWindow(QMainWindow):
|
||||
elif self.mode == "ECG":
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Input": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
"Save": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID))))
|
||||
},
|
||||
"Mode": self.mode
|
||||
@ -111,7 +112,7 @@ class SettingWindow(QMainWindow):
|
||||
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
|
||||
self.config["OutputConfig"]["Freq"] = self.ui.spinBox_output_freq.value()
|
||||
|
||||
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
|
||||
with open(Params.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
@ -123,33 +124,33 @@ class SettingWindow(QMainWindow):
|
||||
if self.mode == "BCG":
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ORGBCG_RAW +
|
||||
Path(Filename.ORGBCG_RAW +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Filename.PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.BCG_FILTER +
|
||||
Path(Filename.BCG_FILTER +
|
||||
str(self.ui.spinBox_output_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
elif self.mode == "ECG":
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ECG_RAW +
|
||||
Path(Filename.ECG_RAW +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Filename.PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.ECG_FILTER +
|
||||
Path(Filename.ECG_FILTER +
|
||||
str(self.ui.spinBox_output_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
Params.ENDSWITH_TXT))))
|
||||
else:
|
||||
raise ValueError("模式不存在")
|
||||
|
||||
@ -205,7 +206,7 @@ class MainWindow_preprocess(QMainWindow):
|
||||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||||
|
||||
@ -239,7 +240,8 @@ class MainWindow_preprocess(QMainWindow):
|
||||
QApplication.processEvents()
|
||||
|
||||
# 清空画框
|
||||
self.ax0.clear()
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
@ -363,7 +365,7 @@ class MainWindow_preprocess(QMainWindow):
|
||||
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
|
||||
|
||||
total_rows = len(DataFrame(self.data.processed_data.reshape(-1)))
|
||||
chunk_size = ConfigParams.PREPROCESS_SAVE_CHUNK_SIZE
|
||||
chunk_size = Params.PREPROCESS_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
@ -385,9 +387,10 @@ class MainWindow_preprocess(QMainWindow):
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
def reset_axes(self):
|
||||
self.ax0.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
if self.ax0 is not None:
|
||||
self.ax0.clear()
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
|
||||
class Data:
|
||||
@ -398,31 +401,28 @@ class Data:
|
||||
|
||||
def open_file(self):
|
||||
if Config["Mode"] == "BCG":
|
||||
signal = ConfigParams.ORGBCG_RAW
|
||||
save = ConfigParams.BCG_FILTER
|
||||
signal = Filename.ORGBCG_RAW
|
||||
save = Filename.BCG_FILTER
|
||||
elif Config["Mode"] == "ECG":
|
||||
signal = ConfigParams.ECG_RAW
|
||||
save = ConfigParams.ECG_FILTER
|
||||
signal = Filename.ECG_RAW
|
||||
save = Filename.ECG_FILTER
|
||||
else:
|
||||
raise ValueError("模式不存在")
|
||||
if Path(Config["Path"]["Input"]).is_file():
|
||||
Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent)
|
||||
|
||||
if not Path(Config["Path"]["Input"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input"], signal)
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input"], signal, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input"] = result.data["path"]
|
||||
Config["InputConfig"]["Freq"] = result.data["freq"]
|
||||
Config["Path"]["Save"] = str(
|
||||
Path(Config["Path"]["Save"]) / Path(save + str(Config["OutputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
|
||||
Path(Config["Path"]["Save"]) / Path(save + str(Config["OutputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
|
||||
else:
|
||||
return result
|
||||
|
||||
try:
|
||||
self.raw_data = read_csv(Config["Path"]["Input"],
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
@ -474,9 +474,6 @@ class Data:
|
||||
return Result().success(info=Constants.PREPROCESS_FINISHED)
|
||||
|
||||
def save(self, chunk):
|
||||
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if self.processed_data is None:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
|
||||
|
||||
1595
func/Module_resp_quality_label.py
Normal file
1595
func/Module_resp_quality_label.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,23 +2,82 @@ from PySide6.QtGui import QIntValidator, QDoubleValidator
|
||||
from matplotlib.ticker import FuncFormatter
|
||||
|
||||
|
||||
class ConfigParams:
|
||||
class Filename:
|
||||
# 文件命名
|
||||
PATH_ORGBCG_TEXT: str = "OrgBCG_Text"
|
||||
PATH_PSG_TEXT: str = "PSG_Text"
|
||||
PATH_ORGBCG_ALIGNED: str = "OrgBCG_Aligned"
|
||||
PATH_PSG_ALIGNED: str = "PSG_Aligned"
|
||||
PATH_ORGBCG_ORIGIN: str = "OrgBCG_Origin"
|
||||
PATH_PSG_ORIGIN: str = "PSG_Origin"
|
||||
PATH_LABEL: str = "Label"
|
||||
PATH_REVEIVE_ORIGIN: str = "Receive_Origin"
|
||||
PATH_REPORT: str = "Report"
|
||||
PATH_SAMPID: str = "<sampID>"
|
||||
SUFFIX_FREQ: str = "采样率"
|
||||
|
||||
# Folder: OrgBCG_Text
|
||||
ORGBCG_RAW: str = "OrgBCG_Raw_"
|
||||
BCG_FILTER: str = "BCG_Filter_"
|
||||
JPEAK_REVISE: str = "Jpeak_revise_"
|
||||
JPEAK_REVISE_CORRECTED: str = "Jpeak_revise_corrected_"
|
||||
|
||||
# Folder: PSG_Text
|
||||
ECG_RAW: str = "ECG II_Raw_"
|
||||
THO_RAW: str = "Effort Tho_Raw_"
|
||||
ABD_RAW: str = "Effort Abd_Raw_"
|
||||
FLOWT_RAW: str = "Flow T_Raw_"
|
||||
FLOWP_RAW: str = "Flow P_Raw_"
|
||||
SNORE_RAW: str = "Snore_Raw_"
|
||||
SPO2_RAW: str = "SpO2_Raw_"
|
||||
FIVE_CLASS_RAW: str = "5_class_Raw_"
|
||||
STARTTIME_RAW: str = "StartTime_Raw"
|
||||
SA_LABEL_RAW: str = "SA Label_Raw"
|
||||
ECG_FILTER: str = "ECG_Filter_"
|
||||
RPEAK_FINAL: str = "Rpeak_final_"
|
||||
RPEAK_FINAL_CORRECTED: str = "Rpeak_final_corrected_"
|
||||
|
||||
# Folder: OrgBCG_Aligned
|
||||
ORGBCG_SYNC: str = "OrgBCG_Sync_"
|
||||
BCG_SYNC: str = "BCG_Sync_"
|
||||
|
||||
# Folder: PSG_Aligned
|
||||
ECG_SYNC: str = "ECG_Sync_"
|
||||
THO_SYNC: str = "Effort Tho_Sync_"
|
||||
ABD_SYNC: str = "Effort Abd_Sync_"
|
||||
FLOWT_SYNC: str = "Flow T_Sync_"
|
||||
FLOWP_SYNC: str = "Flow P_Sync_"
|
||||
SNORE_SYNC: str = "Snore_Sync_"
|
||||
SPO2_SYNC: str = "SpO2_Sync_"
|
||||
FIVE_CLASS_SYNC: str = "5_class_Sync_"
|
||||
SA_LABEL_SYNC: str = "SA Label_Sync"
|
||||
JPEAK_SYNC: str = "Jpeak_Sync_"
|
||||
RPEAK_SYNC: str = "Rpeak_Sync_"
|
||||
|
||||
# Folder: Label
|
||||
APPROXIMATELY_ALIGN_INFO: str = "Approximately_Align_Info"
|
||||
PRECISELY_ALIGN_INFO: str = "Precisely_Align_Info"
|
||||
ARTIFACT_A: str = "Artifact_a_"
|
||||
ARTIFACT_B: str = "Artifact_b_"
|
||||
ARTIFACT_C: str = "Artifact_c_"
|
||||
SA_LABEL_CORRECTED: str = "SA Label_corrected"
|
||||
SA_LABEL_ADD: str = "SA Label_add"
|
||||
RESP_QUALITY_LABEL: str = "Resp_quality_label"
|
||||
THO_PEAK: str = "Tho_peak_"
|
||||
SQ_LABEL_10S: str = "SQ_label_10s"
|
||||
SQ_LABEL_30S: str = "SQ_label_30s"
|
||||
|
||||
|
||||
class Params:
|
||||
|
||||
# 公共
|
||||
PUBLIC_CONFIG_FILE_PATH: str = "./config/Config_public.yaml"
|
||||
PUBLIC_PATH_ORGBCG_TEXT: str = "OrgBCG_Text"
|
||||
PUBLIC_PATH_PSG_TEXT: str = "PSG_Text"
|
||||
PUBLIC_PATH_ORGBCG_ALIGNED: str = "OrgBCG_Aligned"
|
||||
PUBLIC_PATH_PSG_ALIGNED: str = "PSG_Aligned"
|
||||
PUBLIC_PATH_LABEL: str = "Label"
|
||||
PUBLIC_CONFIG_NEW_CONTENT = {
|
||||
"Path": {
|
||||
"Root": ""
|
||||
}
|
||||
}
|
||||
UTF8_ENCODING: str = "utf-8"
|
||||
# 目前用到这个编码的地方:
|
||||
# <BCG的质量评估打标>里的保存和读取csv文件的地方(注意的是,读取原始数据时依然使用UTF-8)
|
||||
GBK_ENCODING: str = "gbk"
|
||||
ENDSWITH_TXT: str = ".txt"
|
||||
ENDSWITH_CSV: str = ".csv"
|
||||
@ -30,45 +89,6 @@ class ConfigParams:
|
||||
VALIDATOR_INTEGER = QIntValidator(-2**31, 2**31 - 1)
|
||||
VALIDATOR_DOUBLE = QDoubleValidator(-1e100, 1e100, 10)
|
||||
|
||||
# 文件命名
|
||||
ORGBCG_RAW: str = "OrgBCG_Raw_"
|
||||
ECG_RAW: str = "ECG II_Raw_"
|
||||
THO_RAW: str = "Effort Tho_Raw_"
|
||||
ABD_RAW: str = "Effort Abd_Raw_"
|
||||
FLOWT_RAW: str = "Flow T_Raw_"
|
||||
FLOWP_RAW: str = "Flow P_Raw_"
|
||||
SNORE_RAW: str = "Snore_Raw_"
|
||||
SPO2_RAW: str = "SpO2_Raw_"
|
||||
FIVE_CLASS_RAW: str = "5_class_Raw_"
|
||||
STARTTIME_RAW: str = "StartTime_Raw_"
|
||||
SA_LABEL_RAW: str = "SA Label_Raw_"
|
||||
BCG_FILTER: str = "BCG_Filter_"
|
||||
ECG_FILTER: str = "ECG_Filter_"
|
||||
JPEAK_REVISE: str = "Jpeak_revise_"
|
||||
RPEAK_FINAL: str = "Rpeak_final_"
|
||||
JPEAK_REVISE_CORRECTED: str = "Jpeak_revise_corrected_"
|
||||
RPEAK_FINAL_CORRECTED: str = "Rpeak_final_corrected_"
|
||||
APPROXIMATELY_ALIGN_INFO: str = "Approximately_Align_Info"
|
||||
PRECISELY_ALIGN_INFO: str = "Precisely_Align_Info"
|
||||
ARTIFACT_A: str = "Artifact_a"
|
||||
ARTIFACT_B: str = "Artifact_b"
|
||||
ARTIFACT_C: str = "Artifact_c"
|
||||
BCG_SYNC: str = "BCG_Sync_"
|
||||
ECG_SYNC: str = "ECG_Sync_"
|
||||
JPEAK_SYNC: str = "Jpeak_Sync_"
|
||||
RPEAK_SYNC: str = "Rpeak_Sync_"
|
||||
ORGBCG_SYNC: str = "OrgBCG_Sync_"
|
||||
THO_SYNC: str = "Effort Tho_Sync_"
|
||||
ABD_SYNC: str = "Effort Abd_Sync_"
|
||||
FLOWT_SYNC: str = "Flow T_Sync_"
|
||||
FLOWP_SYNC: str = "Flow P_Sync_"
|
||||
SNORE_SYNC: str = "Snore_Sync_"
|
||||
SPO2_SYNC: str = "SpO2_Sync_"
|
||||
FIVE_CLASS_SYNC: str = "5_class_Sync_"
|
||||
SA_LABEL_SYNC: str = "SA Label_Sync"
|
||||
SA_LABEL_CORRECTED: str = "SA Label_corrected"
|
||||
SA_LABEL_ADD: str = "SA Label_add"
|
||||
|
||||
# 数据粗同步
|
||||
APPROXIMATELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_approximately_align.yaml"
|
||||
APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
|
||||
@ -195,29 +215,29 @@ class ConfigParams:
|
||||
CUT_PSG_CONFIG_NEW_CONTENT: dict = {
|
||||
"ECGFreq": 1000,
|
||||
"ChannelInput": {
|
||||
"Effort Tho": THO_RAW,
|
||||
"Effort Abd": ABD_RAW,
|
||||
"Flow T": FLOWT_RAW,
|
||||
"Flow P": FLOWP_RAW,
|
||||
"Snore": SNORE_RAW,
|
||||
"SpO2": SPO2_RAW,
|
||||
"5_class": FIVE_CLASS_RAW
|
||||
"Effort Tho": Filename.THO_RAW,
|
||||
"Effort Abd": Filename.ABD_RAW,
|
||||
"Flow T": Filename.FLOWT_RAW,
|
||||
"Flow P": Filename.FLOWP_RAW,
|
||||
"Snore": Filename.SNORE_RAW,
|
||||
"SpO2": Filename.SPO2_RAW,
|
||||
"5_class": Filename.FIVE_CLASS_RAW
|
||||
},
|
||||
"LabelInput": {
|
||||
"SA Label": SA_LABEL_RAW
|
||||
"SA Label": Filename.SA_LABEL_RAW
|
||||
},
|
||||
"StartTime": STARTTIME_RAW,
|
||||
"StartTime": Filename.STARTTIME_RAW,
|
||||
"ChannelSave": {
|
||||
"Effort Tho": THO_SYNC,
|
||||
"Effort Abd": ABD_SYNC,
|
||||
"Flow T": FLOWT_SYNC,
|
||||
"Flow P": FLOWP_SYNC,
|
||||
"Snore": SNORE_SYNC,
|
||||
"SpO2": SPO2_SYNC,
|
||||
"5_class": FIVE_CLASS_SYNC
|
||||
"Effort Tho": Filename.THO_SYNC,
|
||||
"Effort Abd": Filename.ABD_SYNC,
|
||||
"Flow T": Filename.FLOWT_SYNC,
|
||||
"Flow P": Filename.FLOWP_SYNC,
|
||||
"Snore": Filename.SNORE_SYNC,
|
||||
"SpO2": Filename.SPO2_SYNC,
|
||||
"5_class": Filename.FIVE_CLASS_SYNC
|
||||
},
|
||||
"LabelSave": {
|
||||
"SA Label": SA_LABEL_SYNC
|
||||
"SA Label": Filename.SA_LABEL_SYNC
|
||||
},
|
||||
"EndWith": {
|
||||
"Effort Tho": ENDSWITH_TXT,
|
||||
@ -251,6 +271,44 @@ class ConfigParams:
|
||||
ARTIFACT_LABEL_LABEL_TRANSPARENCY: float = 0.3
|
||||
ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY: str = "Z"
|
||||
|
||||
# BCG的质量标注
|
||||
BCG_QUALITY_LABEL_CONFIG_FILE_PATH: str = "./config/Config_bcg_quality_label.yaml"
|
||||
BCG_QUALITY_LABEL_CONFIG_NEW_CONTENT: dict = {
|
||||
"InputConfig": {
|
||||
"BCGFreq": 1000,
|
||||
"UseFreq": 1000
|
||||
}
|
||||
}
|
||||
BCG_QUALITY_LABEL_BTN_PREV_SHORTCUT_KEY: str = "A"
|
||||
BCG_QUALITY_LABEL_BTN_NEXT_SHORTCUT_KEY: str = "D"
|
||||
|
||||
# 呼吸可用性及间期标注
|
||||
RESP_QUALITY_LABEL_CONFIG_FILE_PATH: str = "./config/Config_resp_quality_label.yaml"
|
||||
RESP_QUALITY_LABEL_CONFIG_NEW_CONTENT: dict = {
|
||||
"InputConfig": {
|
||||
"OrgBCGFreq": 1000,
|
||||
"ThoFreq": 100,
|
||||
"OrgBCGUseFreq": 1000,
|
||||
"ThoUseFreq": 100
|
||||
},
|
||||
"Threshold": {
|
||||
"Low": 0.65,
|
||||
"High": 0.8
|
||||
},
|
||||
"FindPeaks" : {
|
||||
"MinInterval": 300,
|
||||
"MinHeight": 0.1
|
||||
},
|
||||
"Filter": {
|
||||
"BandPassLow": 0.1,
|
||||
"BandPassHigh": 1
|
||||
}
|
||||
}
|
||||
RESP_QUALITY_LABEL_PREPROCESS_FC: int = 1
|
||||
RESP_QUALITY_LABEL_PARTS_TIME_SEC: int = 30
|
||||
RESP_QUALITY_LABEL_LABEL_TRANSPARENCY: float = 0.2
|
||||
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
|
||||
|
||||
# 睡眠呼吸暂停事件标注
|
||||
SA_LABEL_CONFIG_FILE_PATH: str = "./config/Config_SA_label.yaml"
|
||||
SA_LABEL_CONFIG_NEW_CONTENT: dict = {
|
||||
@ -281,62 +339,10 @@ class ConfigParams:
|
||||
SA_LABEL_RADIOBUTTON_2_CLASS_SHORTCUT_KEY: str = "I"
|
||||
SA_LABEL_RADIOBUTTON_3_CLASS_SHORTCUT_KEY: str = "O"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 质量打标
|
||||
BCG_QUALITY_LABEL_INPUT_BCG_FILENAME: str = "BCG_sync_"
|
||||
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME: str = "Artifact_a"
|
||||
BCG_QUALITY_LABEL_SAVE_FILENAME: str = "SQ_label_"
|
||||
|
||||
BCG_QUALITY_LABEL_INPUT_DEFAULT_FS: int = 1000
|
||||
|
||||
BCG_QUALITY_LABEL_SAVE_MODE_10S: str = "10s"
|
||||
BCG_QUALITY_LABEL_SAVE_MODE_30S: str = "30s"
|
||||
|
||||
BCG_QUALITY_LABEL_MODE_10S_LENGTH = 10 * BCG_QUALITY_LABEL_INPUT_DEFAULT_FS
|
||||
BCG_QUALITY_LABEL_MODE_30S_LENGTH = 30 * BCG_QUALITY_LABEL_INPUT_DEFAULT_FS
|
||||
|
||||
# 呼吸可用性及间期标注
|
||||
RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME: str = "orgBcg_sync_"
|
||||
RESP_QUALITY_LABEL_INPUT_THO_FILENAME: str = "Effort_Tho_sync_"
|
||||
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME: str = "Artifact_a"
|
||||
RESP_QUALITY_LABEL_SAVE_RESP_QUALITY_LABNEL_FILENAME: str = "Resp_quality_label"
|
||||
RESP_QUALITY_LABEL_SAVE_THO_PEAK_FILENAME: str = "Tho_peak"
|
||||
|
||||
RESP_QUALITY_LABEL_INPUT_XINXIAO_DEFAULT_FS: int = 1000
|
||||
RESP_QUALITY_LABEL_INPUT_THO_DEFAULT_FS: int = 200
|
||||
|
||||
RESP_QUALITY_LABEL_PARTS_TIME_SEC: int = 30
|
||||
RESP_QUALITY_LABEL_PREPROCESS_FC: int = 1
|
||||
|
||||
RESP_QUALITY_LABEL_THRESHOLD1_DEFAULT: float = 0.65
|
||||
RESP_QUALITY_LABEL_THRESHOLD2_DEFAULT: float = 0.8
|
||||
RESP_QUALITY_LABEL_FINDPEAKS_MIN_INTERVAL_DEFAULT: int = 300
|
||||
RESP_QUALITY_LABEL_FINDPEAKS_MIN_HEIGHT_DEFAULT: float = 0.1
|
||||
RESP_QUALITY_LABEL_CUSTOM_LOW_DEFAULT: float = 0.1
|
||||
RESP_QUALITY_LABEL_CUSTOM_HIGH_DEFAULT: float = 1
|
||||
|
||||
RESP_QUALITY_LABEL_LABEL_TRANSPARENCY: float = 0.2
|
||||
|
||||
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
|
||||
|
||||
|
||||
# 睡眠呼吸暂停事件打标
|
||||
|
||||
|
||||
# 禁止实例化
|
||||
def __new__(cls):
|
||||
raise TypeError("Constants class cannot be instantiated")
|
||||
|
||||
|
||||
# 禁止修改常量
|
||||
@classmethod
|
||||
def __setattr__(cls, key, value):
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from func.utils.ConfigParams import ConfigParams
|
||||
from func.utils.ConfigParams import Params
|
||||
|
||||
|
||||
class Constants:
|
||||
@ -94,16 +94,18 @@ class Constants:
|
||||
"Path_Not_Exist": "(路径不存在)",
|
||||
"File_Not_Exist": "(数据文件不存在)",
|
||||
"File_More_Than_One": "(数据文件超过一个)",
|
||||
"Data_Frequency_Not_In_Filename": "(无法找到文件名中的数据频率信息)",
|
||||
"Suffix_Not_Correct": "(文件扩展名不正确)",
|
||||
"Frequency_Not_In_Filename": "(数据频率不在文件名中)",
|
||||
"Data_Not_Exist": "(数据不存在)",
|
||||
"Model_File_Not_Exist": "(模型文件不存在)",
|
||||
"Model_Path_Not_Exist": "(模型文件不存在)",
|
||||
"Cut_Data_Length_not_Correct": "(切割数据时长度不正确)",
|
||||
"Align_Label_SALabel_Format_not_Correct": "(映射标签时SA Label中的文件格式不正确)",
|
||||
"Filename_Format_not_Correct": "(文件名格式不正确)",
|
||||
"Method_Not_Exist": "(检测方法不存在)",
|
||||
"Data_Length_not_Correct": "(orgBcg和BCG长度不匹配)",
|
||||
"Artifact_Format_Not_Correct": "(体动长度或格式不正确)",
|
||||
"Get_Artifact_Format_Exception": "(获取体动长度或格式异常)",
|
||||
"Data_Length_Not_Correct": "(信号长度不正确)",
|
||||
|
||||
"Open_Data_Exception": "(打开数据异常)",
|
||||
"Process_Exception": "(处理异常)",
|
||||
@ -132,7 +134,9 @@ class Constants:
|
||||
"Get_File_and_Freq_Excepetion": "(检查文件是否存在并获取其数据采样率异常)",
|
||||
"Update_tableWidget_Exception": "(更新表格异常)",
|
||||
"Update_Info_Exception": "(更新信息异常)",
|
||||
"Get_Artifact_Format_Exception": "(获取体动长度或格式异常)",
|
||||
"Label_Format_Exception": "(获取标签格式异常)",
|
||||
"Calculate_Peak_Exception": "(计算峰值异常)",
|
||||
|
||||
"res_orgBcg_Not_Exist": "(切割后orgBcg不存在)",
|
||||
"res_BCG_Not_Exist": "(切割后BCG不存在)",
|
||||
@ -240,7 +244,7 @@ class Constants:
|
||||
LABEL_CHECK_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
|
||||
LABEL_CHECK_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
|
||||
LABEL_CHECK_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无新增或删除点"
|
||||
LABEL_CHECK_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({ConfigParams.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
|
||||
LABEL_CHECK_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({Params.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
|
||||
|
||||
# 数据精同步
|
||||
PRECISELY_ALIGN_PROCESSING_DATA: str = "正在处理数据"
|
||||
@ -296,7 +300,7 @@ class Constants:
|
||||
PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT: str = "Selected Point"
|
||||
PRECISELY_ALIGN_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无有效点"
|
||||
PRECISELY_ALIGN_RECOVER_SCALE: str = "尺度恢复"
|
||||
PRECISELY_ALIGN_ACTION_GET_RANGE_NAME: str = f"设置范围({ConfigParams.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY})"
|
||||
PRECISELY_ALIGN_ACTION_GET_RANGE_NAME: str = f"设置范围({Params.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY})"
|
||||
|
||||
# 冗余数据切割和标签映射
|
||||
CUT_PSG_GETTING_FILE_AND_FREQ: str = "正在获取文件及其采样率"
|
||||
@ -324,11 +328,17 @@ class Constants:
|
||||
ARTIFACT_LABEL_JUMP_ARTIFACT: str = "跳转到体动"
|
||||
ARTIFACT_LABEL_RECOVER_SCALE: str = "尺度恢复"
|
||||
ARTIFACT_LABEL_MISS_ARGS: str = "打标参数未填写"
|
||||
ARTIFACT_LABEL_OVERLAPPING: str = "当前所打标的片段存在重合,重合片段序号:"
|
||||
ARTIFACT_LABEL_MERGE: str = "当前所打标的片段距离附近片段不到2秒,片段序号:"
|
||||
ARTIFACT_LABEL_MULTIPLE_ARTIFACT_COVER_OR_DELETE: str = "所选区域包含多种类型的体动,是否需要删除它们并使用新标注进行覆盖?所选区域中含有的体动序号:"
|
||||
ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE: str = "所选区域前2秒内有与当前标注相同类型的体动,将执行合并"
|
||||
ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE: str = "所选区域后2秒内有与当前标注相同类型的体动,将执行合并"
|
||||
ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE: str = "所选区域前后2秒内都有与当前标注相同类型的体动,将执行合并"
|
||||
ARTIFACT_LABEL_FRONT_TWO_SECONDS_WARNING: str = "所选区域前2秒内有与当前标注相同类型的体动,仅进行提示"
|
||||
ARTIFACT_LABEL_BACK_TWO_SECONDS_WARNING: str = "所选区域后2秒内有与当前标注相同类型的体动,仅进行提示"
|
||||
ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_WARNING: str = "所选区域前后2秒内都有与当前标注相同类型的体动,仅进行提示"
|
||||
ARTIFACT_LABEL_SINGLE_TYPE_NOT_EQUAL: str = "所选区域仅包含一种类型的体动,但其类型与当前标注的类型不匹配,是否需要删除它们并使用新标注覆盖?所选区域中含有的体动序号:"
|
||||
ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY: str = "体动被删除"
|
||||
ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE: str = "需要被删除的体动不存在"
|
||||
ARTIFACT_LABEL_ACTION_LABEL: str = f"标注体动({ConfigParams.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY})"
|
||||
ARTIFACT_LABEL_ACTION_LABEL: str = f"标注体动({Params.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY})"
|
||||
|
||||
ARTIFACT_LABEL_LABELBTN_STYLE_1: str = """
|
||||
QPushButton {
|
||||
@ -381,6 +391,93 @@ class Constants:
|
||||
background-color: #00ff00; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
|
||||
# BCG的质量标注
|
||||
BCG_QUALITY_LABEL_COLUMN_LABEL: str = "label"
|
||||
BCG_QUALITY_LABEL_COLUMN_REMARK: str = "remark"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_SIGNAL: str = "BCG"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_LONGEST_CONTINUOUS: str = "Longest_Continuous"
|
||||
BCG_QUALITY_LABEL_10S_A: str = "a1"
|
||||
BCG_QUALITY_LABEL_10S_B: str = "b1"
|
||||
BCG_QUALITY_LABEL_10S_C: str = "c1"
|
||||
BCG_QUALITY_LABEL_30S_A1: str = "a1"
|
||||
BCG_QUALITY_LABEL_30S_A2: str = "a2"
|
||||
BCG_QUALITY_LABEL_30S_B1: str = "b1"
|
||||
BCG_QUALITY_LABEL_30S_B2: str = "b2"
|
||||
BCG_QUALITY_LABEL_30S_C: str = "c1"
|
||||
BCG_QUALITY_LABEL_TOBELABELED: str = "f1"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART_UNLABELED: str = "前面的片段都被打标,将跳转至第1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART_UNLABELED: str = "后面的片段都被打标,将跳转至最后1段信号"
|
||||
BCG_QUALITY_LABEL_LABELED_FINISHED: str = "该份数据打标已全部完成"
|
||||
BCG_QUALITY_LABEL_VIEWING_PART: str = "正在查看信号段"
|
||||
BCG_QUALITY_LABEL_JUMP_PART: str = "跳转到片段"
|
||||
BCG_QUALITY_LABEL_LABEL_ALL_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_LABEL_ARTIFACT_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有带有体动的片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_LABELBTN_STYLE: str = """
|
||||
QPushButton {
|
||||
background-color: orange; /* 设置背景颜色 */
|
||||
padding: 10px; /* 设置内边距 */
|
||||
border: 2px solid darkblue; /* 设置边框 */
|
||||
border-radius: 10px; /* 设置圆角 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: yellow; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
|
||||
|
||||
# 呼吸可用性及间期标注
|
||||
RESP_QUALITY_LABEL_CALCULATING_PEAK: str = "正在计算峰值"
|
||||
RESP_QUALITY_LABEL_CALCULATE_FINISHED: str = "计算完成"
|
||||
RESP_QUALITY_LABEL_CALCULATE_FAILURE: str = "计算失败"
|
||||
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_ORGBCG: str = "BDR_Sync by filter OrgBCG_Sync"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_THO: str = "THO_Sync after preprocess"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_THO_PEAKS: str = "Tho_peak"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_BDR_TITLE: str = "Spectrum of BDR_sync by filter OrgBCG_Sync"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_THO_TITLE: str = "Spectrum of THO_sync after preprocess"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_ORGBCG_LABEL: str = "OrgBCG"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_BDR_LABEL: str = "BDR"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_THO_LABEL: str = "Tho"
|
||||
RESP_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
|
||||
RESP_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
|
||||
RESP_QUALITY_LABEL_PREV_PART: str = "上一个片段,index "
|
||||
RESP_QUALITY_LABEL_NEXT_PART: str = "下一个片段,index "
|
||||
RESP_QUALITY_LABEL_JUMP: str = "跳转到片段,index "
|
||||
RESP_QUALITY_LABEL_LABEL_SUCCESSFULLY: str = "片段标注成功"
|
||||
RESP_QUALITY_LABEL_LABEL_TYPE: str = "标注类型为:"
|
||||
RESP_QUALITY_LABEL_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
|
||||
RESP_QUALITY_LABEL_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
|
||||
RESP_QUALITY_LABEL_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无新增或删除点"
|
||||
RESP_QUALITY_LABEL_CUSTOM_FILTER_ARGS_ERROR: str = "OrgBCG带通滤波频率设置范围应为数字,范围是0~1"
|
||||
RESP_QUALITY_LABEL_AUTOLABEL_ARGS_ERROR: str = "人工标注阈值设置范围应为数字,范围是0~1"
|
||||
RESP_QUALITY_LABEL_CHECK_ARGS_QUESTION_CONTENT: str = "你确定要执行此操作吗,请确保参数输入正确"
|
||||
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({Params.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
|
||||
RESP_QUALITY_LABEL_A_QUALITY: int = 1
|
||||
RESP_QUALITY_LABEL_B_QUALITY: int = 0
|
||||
RESP_QUALITY_LABEL_C_QUALITY: int = -1
|
||||
RESP_QUALITY_LABEL_KEY_VALUE = {
|
||||
1: "Good",
|
||||
0: "Bad",
|
||||
-1: "None"
|
||||
}
|
||||
RESP_QUALITY_LABEL_FIGTOOLBAR_SPECTRUM_STYLESHEET: str = """
|
||||
QToolBar {
|
||||
border: 1px;
|
||||
spacing: 2px; /* 设置工具栏按钮之间的间距 */
|
||||
}
|
||||
QToolButton {
|
||||
height: 20px; /* 设置工具栏按钮的高度 */
|
||||
width: 20px; /* 设置工具栏按钮的宽度 */
|
||||
font-size: 8px; /* 设置按钮文字大小 */
|
||||
}
|
||||
QToolButton::menu-button {
|
||||
width: 0px; /* 隐藏下拉菜单按钮 */
|
||||
}
|
||||
"""
|
||||
|
||||
# 睡眠呼吸暂停事件标注
|
||||
SA_LABEL_JUMP: str = "跳转到事件"
|
||||
SA_LABEL_VIEWING_FIRST: str = "你正在查看第1个事件"
|
||||
@ -398,133 +495,6 @@ class Constants:
|
||||
SA_LABEL_LENGTH_LESS_THEN_10S: str = "当前标注的事件的持续时间小于10秒"
|
||||
SA_LABEL_WRONG_ARGS: str = "起始时间和终止时间输入错误"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 质量打标
|
||||
BCG_QUALITY_LABEL_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.BCG_QUALITY_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<BCG的质量标注>"
|
||||
BCG_QUALITY_LABEL_FILES_FOUND: str = f"找到{ConfigParams.BCG_QUALITY_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT}"
|
||||
BCG_QUALITY_LABEL_HISTORICAL_SAVE_FOUND: str = f"找到历史存档文件{ConfigParams.BCG_QUALITY_LABEL_SAVE_FILENAME}{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_10S}{ConfigParams.ENDSWITH_CSV}或{ConfigParams.BCG_QUALITY_LABEL_SAVE_FILENAME}{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_30S}{ConfigParams.ENDSWITH_CSV},已成功读取"
|
||||
BCG_QUALITY_LABEL_MODE_UNSELECTED: str = "显示模式未选择"
|
||||
BCG_QUALITY_LABEL_INPUT_SIGNAL_FAILURE: str = "导入信号失败,请检查信号长度"
|
||||
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_FORMAT: str = "导入体动失败,请检查体动标签格式"
|
||||
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_LENGTH: str = "导入体动失败,请检查体动长度是否为4的倍数"
|
||||
|
||||
BCG_QUALITY_LABEL_RUNNING: str = "开始执行任务<BCG的质量评估标注>"
|
||||
BCG_QUALITY_LABEL_10S_MODE: str = f"{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_10S}_MODE"
|
||||
BCG_QUALITY_LABEL_30S_MODE: str = f"{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_30S}_MODE"
|
||||
BCG_QUALITY_LABEL_COLUMN_LABEL: str = "label"
|
||||
BCG_QUALITY_LABEL_COLUMN_REMARK: str = "remark"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART_UNLABELED: str = "前面的片段都被打标,将跳转至第1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART_UNLABELED: str = "后面的片段都被打标,将跳转至最后1段信号"
|
||||
BCG_QUALITY_LABEL_LABELED_FINISHED: str = "该份数据打标已全部完成"
|
||||
BCG_QUALITY_LABEL_VIEWING_PART: str = "正在查看信号段"
|
||||
BCG_QUALITY_LABEL_JUMP_PART: str = "跳转到片段"
|
||||
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_HIGHLIGHT_LONGEST_CONTINUOUS: str = "点击了<高亮最长连续>"
|
||||
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_DISPLAY_AFTERFILTER: str = "点击了<去除工频噪声>"
|
||||
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_EXAMINE_TOBOLABELED: str = "点击了<仅查未标片段>"
|
||||
BCG_QUALITY_LABEL_LABEL_ALL_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_LABEL_ALL_TO_TYPE_C: str = "已将所有片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_LABEL_ARTIFACT_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有带有体动的片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_LABEL_ARTIFACT_TO_TYPE_C: str = "已将所有带有体动的片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_SIGNAL: str = "BCG"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_LONGEST_CONTINUOUS: str = "Longest_Continuous"
|
||||
BCG_QUALITY_LABEL_10S_A: str = "a"
|
||||
BCG_QUALITY_LABEL_10S_B: str = "b"
|
||||
BCG_QUALITY_LABEL_10S_C: str = "c"
|
||||
BCG_QUALITY_LABEL_10S_A_LIST: str = "label_a"
|
||||
BCG_QUALITY_LABEL_10S_B_LIST: str = "label_b"
|
||||
BCG_QUALITY_LABEL_10S_C_LIST: str = "label_c"
|
||||
BCG_QUALITY_LABEL_30S_A1: str = "a"
|
||||
BCG_QUALITY_LABEL_30S_A2: str = "b"
|
||||
BCG_QUALITY_LABEL_30S_B1: str = "c"
|
||||
BCG_QUALITY_LABEL_30S_B2: str = "d"
|
||||
BCG_QUALITY_LABEL_30S_C: str = "e"
|
||||
BCG_QUALITY_LABEL_30S_A1_LIST: str = "label_a1"
|
||||
BCG_QUALITY_LABEL_30S_A2_LIST: str = "label_a2"
|
||||
BCG_QUALITY_LABEL_30S_B1_LIST: str = "label_b1"
|
||||
BCG_QUALITY_LABEL_30S_B2_LIST: str = "label_b2"
|
||||
BCG_QUALITY_LABEL_30S_C_LIST: str = "label_c"
|
||||
BCG_QUALITY_LABEL_tobeLabeled: str = "f"
|
||||
BCG_QUALITY_LABEL_tobeLabeled_LIST: str = "label_tobeLabeled"
|
||||
BCG_QUALITY_LABEL_LABELBTN_STYLE: str = """
|
||||
QPushButton {
|
||||
background-color: orange; /* 设置背景颜色 */
|
||||
padding: 10px; /* 设置内边距 */
|
||||
border: 2px solid darkblue; /* 设置边框 */
|
||||
border-radius: 10px; /* 设置圆角 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: yellow; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
|
||||
|
||||
# 呼吸可用性及间期标注
|
||||
RESP_QUALITY_LABEL_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.RESP_QUALITY_LABEL_INPUT_THO_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<呼吸可用性及间期标注>"
|
||||
RESP_QUALITY_LABEL_FILES_FOUND: str = f"找到{ConfigParams.RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.RESP_QUALITY_LABEL_INPUT_THO_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT}"
|
||||
RESP_QUALITY_LABEL_HISTORICAL_SAVE1_FOUND: str = f"找到历史存档文件{ConfigParams.RESP_QUALITY_LABEL_SAVE_RESP_QUALITY_LABNEL_FILENAME}{ConfigParams.ENDSWITH_TXT},已成功读取"
|
||||
RESP_QUALITY_LABEL_HISTORICAL_SAVE2_FOUND: str = f"找到历史存档文件{ConfigParams.RESP_QUALITY_LABEL_SAVE_THO_PEAK_FILENAME}{ConfigParams.ENDSWITH_TXT},已成功读取"
|
||||
RESP_QUALITY_LABEL_INPUT_SIGNAL_FAILURE: str = "导入信号失败,请检查信号长度"
|
||||
RESP_QUALITY_LABEL_INPUT_SUCCESSFULLY: str = "导入数据成功"
|
||||
RESP_QUALITY_LABEL_PREPROCESS_SUCCESSFULLY: str = "导入数据成功"
|
||||
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_FORMAT: str = "导入体动失败,请检查体动标签格式"
|
||||
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_LENGTH: str = "导入体动失败,请检查体动长度是否为4的倍数"
|
||||
|
||||
RESP_QUALITY_LABEL_RUNNING: str = "开始执行任务<呼吸可用性及间期标注>"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_ORGBCG: str = "BDR_sync by filter orgBcg_sync"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_THO: str = "THO_sync after preprocess"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_THO_PEAKS: str = "THO_peak"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
|
||||
RESP_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
|
||||
RESP_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
|
||||
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({ConfigParams.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
|
||||
RESP_QUALITY_LABEL_CUSTOM_NAVIGATIONTOOLBAR_WIDGET_NAME: str = "MainWindow"
|
||||
RESP_QUALITY_LABEL_BUTTON_PRESS_EVENT: str = "button_press_event"
|
||||
RESP_QUALITY_LABEL_BUTTON_RELEASE_EVENT: str = "button_release_event"
|
||||
RESP_QUALITY_LABEL_MOTION_NOTIFY_EVENT: str = "motion_notify_event"
|
||||
RESP_QUALITY_LABEL_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
|
||||
RESP_QUALITY_LABEL_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
|
||||
RESP_QUALITY_LABEL_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无新增或删除点"
|
||||
RESP_QUALITY_LABEL_SAVE_PEAKS_SUCCESSFULLY: str = "保存峰值成功"
|
||||
RESP_QUALITY_LABEL_DATA_NOT_FOUND: str = "数据未导入"
|
||||
RESP_QUALITY_LABEL_LABEL_SUCCESSFULLY: str = "片段标注并保存成功"
|
||||
RESP_QUALITY_LABEL_RESET_SUCCESSFULLY: str = "片段重置并保存成功"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_VLINE: str = "vline"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_HLINE: str = "hline"
|
||||
RESP_QUALITY_LABEL_A_QUALITY: int = 1
|
||||
RESP_QUALITY_LABEL_B_QUALITY: int = 0
|
||||
RESP_QUALITY_LABEL_C_QUALITY: int = -1
|
||||
RESP_QUALITY_LABEL_LABELED: str = "已标注"
|
||||
RESP_QUALITY_LABEL_TOBELABELED: str = "未标注"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_BDR_TITLE: str = "Spectrum of BDR_sync by filter orgBcg_sync"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_THO_TITLE: str = "Spectrum of THO_sync after preprocess"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_ORGBCG_LABEL: str = "orgBcg"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_BDR_LABEL: str = "BDR"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_THO_LABEL: str = "THO"
|
||||
RESP_QUALITY_LABEL_CUSTOM_FILTER_ARGS_ERROR: str = "orgBcg带通滤波频率设置范围应为数字,范围是0~1"
|
||||
RESP_QUALITY_LABEL_AUTOLABEL_ARGS_ERROR: str = "人工标注阈值设置范围应为数字,范围是0~1"
|
||||
RESP_QUALITY_LABEL_CHECK_ARGS_QUESTION_CONTENT: str = "你确定要执行此操作吗,请确保参数输入正确"
|
||||
RESP_QUALITY_LABEL_KEY_VALUE = {
|
||||
1: "Good",
|
||||
0: "Bad",
|
||||
-1: "None"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 禁止实例化
|
||||
def __new__(cls):
|
||||
raise TypeError("Constants class cannot be instantiated")
|
||||
|
||||
@ -177,7 +177,7 @@ class PublicFunc:
|
||||
QApplication.processEvents()
|
||||
|
||||
@staticmethod
|
||||
def examine_file(path_str, filename):
|
||||
def examine_file(path_str, filename, suffix):
|
||||
temp_path = list(
|
||||
Path(path_str).glob(f"{filename}*"))
|
||||
if len(temp_path) == 0:
|
||||
@ -201,8 +201,24 @@ class PublicFunc:
|
||||
info=Constants.INPUT_FAILURE + "\n" +
|
||||
filename + ":" +
|
||||
Constants.FAILURE_REASON["Data_Frequency_Not_In_Filename"])
|
||||
if Path(path).suffix != suffix:
|
||||
return Result().failure(
|
||||
info=Constants.INPUT_FAILURE + "\n" +
|
||||
filename + ":" +
|
||||
Constants.FAILURE_REASON["Suffix_Not_Correct"])
|
||||
data = {
|
||||
"path": str(path),
|
||||
"freq": int(freq)
|
||||
}
|
||||
return Result().success(data=data)
|
||||
return Result().success(data=data)
|
||||
|
||||
@staticmethod
|
||||
def examine_artifact(artifact):
|
||||
# 检查体动标签正确性,长度
|
||||
if len(artifact) % 4 != 0:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
Constants.FAILURE_REASON["Artifact_Format_Not_Correct"])
|
||||
for i in range(0, len(artifact), 4):
|
||||
unit_data = artifact[i:i + 4]
|
||||
if len(unit_data) < 4:
|
||||
break
|
||||
Reference in New Issue
Block a user