1、完善命名规范

2、完成<冗余数据切割和标签映射>的全部代码
This commit is contained in:
2025-05-09 17:21:55 +08:00
parent 9dd7689756
commit aad3dfba49
15 changed files with 567 additions and 272 deletions

307
func/Module_cut_PSG.py Normal file
View File

@ -0,0 +1,307 @@
from ast import literal_eval
from gc import collect
from math import floor
from pathlib import Path
from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication
from numpy import array
from overrides import overrides
from pandas import read_csv, DataFrame
from yaml import dump, load, FullLoader
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from ui.MainWindow.MainWindow_cut_PSG import Ui_MainWindow_cut_PSG
Config = {
}
ButtonState = {
"Default": {
"pushButton_execute": True
},
"Current": {
"pushButton_execute": True
}
}
class MainWindow_cut_PSG(QMainWindow):
def __init__(self):
super(MainWindow_cut_PSG, self).__init__()
self.ui = Ui_MainWindow_cut_PSG()
self.ui.setupUi(self)
self.root_path = None
self.sampID = None
self.__read_config__()
self.data = None
# 初始化进度条
self.ui.progressbar.setStyleSheet(Constants.PROGRESSBAR_STYLE)
self.progressbar = self.ui.progressbar
self.msgBox = QMessageBox()
self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE)
@overrides
def show(self, root_path, sampID):
super().show()
self.root_path = root_path
self.sampID = sampID
PublicFunc.__resetAllButton__(self, ButtonState)
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_PSG_ALIGNED / Path(str(self.sampID)) / (ConfigParams.CUT_PSG_SAVE_ECG_ALIGNINFO_FILENAME + ConfigParams.ENDSWITH_TXT))
}
})
self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys()))
self.ui.plainTextEdit_label.setPlainText(', '.join(Config["LabelInput"].keys()))
self.ui.pushButton_execute.clicked.connect(self.__slot_btn_execute__)
@overrides
def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState)
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
QApplication.processEvents()
# 释放资源
del self.data
self.deleteLater()
collect()
event.accept()
@staticmethod
def __reset__():
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)
with open(ConfigParams.CUT_PSG_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
# 数据回显
self.ui.spinBox_ECGFreq.setValue(Config["ECGFreq"])
def __slot_btn_execute__(self):
PublicFunc.__disableAllButton__(self, ButtonState)
self.data = Data()
Config["ECGFreq"] = self.ui.spinBox_ECGFreq.value()
# 检查文件是否存在并获取其数据采样率
PublicFunc.progressbar_update(self, 1, 5, Constants.CUT_PSG_GETTING_FILE_AND_FREQ, 0)
status, info = self.data.get_file_and_freq()
if not status:
PublicFunc.text_output(self.ui, "(1/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(1/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
# 导入数据
PublicFunc.progressbar_update(self, 2, 5, Constants.INPUTTING_DATA, 10)
status, info = self.data.open_file()
if not status:
PublicFunc.text_output(self.ui, "(2/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(2/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
# 切割数据
PublicFunc.progressbar_update(self, 3, 5, Constants.CUT_PSG_CUTTING_DATA, 40)
status, info = self.data.cut_data()
if not status:
PublicFunc.text_output(self.ui, "(3/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(3/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
# 标签映射
PublicFunc.progressbar_update(self, 4, 5, Constants.CUT_PSG_ALIGNING_LABEL, 60)
status, info = self.data.align_label()
if not status:
PublicFunc.text_output(self.ui, "(4/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(4/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
# 切割数据
PublicFunc.progressbar_update(self, 5, 5, Constants.SAVING_DATA, 70)
status, info = self.data.save()
if not status:
PublicFunc.text_output(self.ui, "(5/5)" + info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(5/5)" + info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
class Data:
def __init__(self):
self.alignInfo = None
self.raw = {key: array([]) for key in Config["ChannelInput"]}
self.freq = {key: 0 for key in Config["ChannelInput"]}
self.SALabel = None
self.startTime = None
def get_file_and_freq(self):
try:
for file_path in Path(Config["Path"]["InputFolder"]).glob('*'):
if file_path.is_file():
file_stem = Path(file_path).stem
for key, prefix in Config["ChannelInput"].items():
if file_stem.startswith(prefix):
freq_str = file_stem.rsplit('_', 1)[1]
try:
freq = int(freq_str)
self.freq[key] = freq
except ValueError:
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Filename_Format_not_Correct"]
for value in self.freq.values():
if value == 0:
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Filename_Format_not_Correct"]
if not any((Config["LabelInput"]["SA Label"] + Config["EndWith"]["SA Label"]) in str(file) for file in Path(Config["Path"]["InputFolder"]).glob('*')):
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"]
if not any((Config["StartTime"] + Config["EndWith"]["StartTime"]) in str(file) for file in Path(Config["Path"]["InputFolder"]).glob('*')):
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"]
if not Path(Config["Path"]["InputAlignInfo"]).exists():
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"]
except Exception:
return False, Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE["Get_File_and_Freq_Excepetion"]
return True, Constants.CUT_PSG_GET_FILE_AND_FREQ_FINISHED
def open_file(self):
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,
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)
self.startTime = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["StartTime"] + Config["EndWith"]["StartTime"])),
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.alignInfo = read_csv(Path(Config["Path"]["InputAlignInfo"]),
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.alignInfo = literal_eval(self.alignInfo[0])
except Exception:
return False, Constants.INPUT_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Read_Data_Exception"]
return True, Constants.INPUT_FINISHED
def cut_data(self):
try:
for key, raw in self.raw.items():
# 转换切割点
ECG_freq = Config["ECGFreq"]
raw_freq = self.freq[key]
duration_second = ((self.alignInfo["cut_index"]["back_ECG"] - self.alignInfo["cut_index"]["front_ECG"]) // 1000) + 1
start_index_cut = floor(self.alignInfo["cut_index"]["front_ECG"] * (raw_freq / ECG_freq))
end_index_cut = start_index_cut + (duration_second * raw_freq)
try:
# 切割信号
self.raw[key] = self.raw[key][start_index_cut:end_index_cut]
except Exception:
return False, Constants.CUT_PSG_CUT_DATA_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Cut_Data_Length_not_Correct"]
except Exception:
return False, Constants.CUT_PSG_CUT_DATA_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Cut_Data_Exception"]
return True, Constants.CUT_PSG_CUT_DATA_FINISHED
def align_label(self):
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["Duration"] = self.SALabel["Duration"].astype(str)
self.SALabel["Duration"] = self.SALabel["Duration"].str.replace(r' \(.*?\)', '', regex=True)
except Exception:
return False, Constants.CUT_PSG_ALIGN_LABEL_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Align_Label_SALabel_Format_not_Correct"]
try:
# 获取记录开始时间
start_time = str(self.startTime[0]).split(" ")[1]
start_time = Data.get_time_to_seconds(start_time)
# 计算起始时间秒数和终止时间秒数
self.SALabel["Start"] = (self.SALabel["Time"].apply(self.get_time_to_seconds) - start_time).apply(
lambda x: x + 24 * 3600 if x < 0 else x).astype(int)
self.SALabel["End"] = self.SALabel["Start"] + self.SALabel["Duration"].astype(float).round(0).astype(int)
# 标签映射
ECG_length = self.alignInfo["cut_index"]["back_ECG"] - self.alignInfo["cut_index"]["front_ECG"]
self.SALabel["Start"] = self.SALabel["Start"] - round((self.alignInfo["cut_index"]["front_ECG"] / 1000))
self.SALabel["End"] = self.SALabel["End"] - round((self.alignInfo["cut_index"]["front_ECG"] / 1000))
self.SALabel = self.SALabel[self.SALabel["End"] >= 0]
self.SALabel.loc[self.SALabel["Start"] < 0, "Start"] = 0
self.SALabel = self.SALabel[self.SALabel["Start"] < ECG_length]
self.SALabel.loc[self.SALabel["End"] >= ECG_length, "End"] = ECG_length - 1
except Exception:
return False, Constants.CUT_PSG_ALIGN_LABEL_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Align_Label_Exception"]
return True, Constants.CUT_PSG_ALIGN_LABEL_FINISHED
def save(self):
for raw in self.raw.values():
if len(raw) == 0:
return False, Constants.SAVING_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Save_Data_not_Exist"]
try:
for key, raw in self.raw.items():
DataFrame(raw.reshape(-1)).to_csv(Path(Config["Path"]["SaveFolder"]) / Path((Config["ChannelSave"][key] + str(self.freq[key]) + Config["EndWith"][key])),
index=False, header=False)
self.SALabel.to_csv(Path(Config["Path"]["SaveFolder"]) / Path((Config["LabelSave"]["SA Label"] + Config["EndWith"]["SA Label"])),
index=False,
encoding="gbk")
except Exception:
return False, Constants.SAVING_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Save_Exception"]
return True, Constants.SAVING_FINISHED
@staticmethod
def get_time_to_seconds(time_str):
h, m, s = map(int, time_str.split(":"))
return h * 3600 + m * 60 + s

View File

@ -41,7 +41,6 @@ ButtonState = {
class SettingWindow(QMainWindow): class SettingWindow(QMainWindow):
def __init__(self, root_path, sampID): def __init__(self, root_path, sampID):
super(SettingWindow, self).__init__() super(SettingWindow, self).__init__()
self.ui = Ui_MainWindow_detect_Jpeak_input_setting() self.ui = Ui_MainWindow_detect_Jpeak_input_setting()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -58,7 +57,6 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH).exists(): if not Path(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH).exists():
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f: with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.DETECT_JPEAK_CONFIG_NEW_CONTENT, f) dump(ConfigParams.DETECT_JPEAK_CONFIG_NEW_CONTENT, f)
@ -87,7 +85,6 @@ class SettingWindow(QMainWindow):
self.ui.plainTextEdit_file_path_save.setPlainText(Config["Path"]["Save"]) self.ui.plainTextEdit_file_path_save.setPlainText(Config["Path"]["Save"])
def __write_config__(self): def __write_config__(self):
# 从界面写入配置 # 从界面写入配置
Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value() Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
Config["Path"]["Input"] = self.ui.plainTextEdit_file_path_input.toPlainText() Config["Path"]["Input"] = self.ui.plainTextEdit_file_path_input.toPlainText()
@ -104,11 +101,9 @@ class SettingWindow(QMainWindow):
self.close() self.close()
def __rollback_config__(self): def __rollback_config__(self):
self.__read_config__() self.__read_config__()
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input.setPlainText( self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
@ -117,10 +112,10 @@ class SettingWindow(QMainWindow):
str(self.ui.spinBox_input_freq.value()) + str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) ConfigParams.ENDSWITH_TXT))))
class MainWindow_detect_Jpeak(QMainWindow): class MainWindow_detect_Jpeak(QMainWindow):
def __init__(self): def __init__(self):
super(MainWindow_detect_Jpeak, self).__init__() super(MainWindow_detect_Jpeak, self).__init__()
self.ui = Ui_MainWindow_detect_Jpeak() self.ui = Ui_MainWindow_detect_Jpeak()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -149,7 +144,6 @@ class MainWindow_detect_Jpeak(QMainWindow):
@overrides @overrides
def show(self, root_path, sampID): def show(self, root_path, sampID):
super().show() super().show()
self.root_path = root_path self.root_path = root_path
self.sampID = sampID self.sampID = sampID
@ -196,7 +190,6 @@ class MainWindow_detect_Jpeak(QMainWindow):
@overrides @overrides
def closeEvent(self, event): def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN)) PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
@ -217,12 +210,10 @@ class MainWindow_detect_Jpeak(QMainWindow):
@staticmethod @staticmethod
def __reset__(): def __reset__():
ButtonState["Current"].update(ButtonState["Default"].copy()) ButtonState["Current"].update(ButtonState["Default"].copy())
ButtonState["Current"]["pushButton_view"] = True ButtonState["Current"]["pushButton_view"] = True
def __plot__(self): def __plot__(self):
# 清空画框 # 清空画框
self.reset_axes() self.reset_axes()
@ -249,7 +240,6 @@ class MainWindow_detect_Jpeak(QMainWindow):
return status, info return status, info
def __update_config__(self): def __update_config__(self):
Config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value() Config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value()
Config["Filter"]["BandPassHigh"] = self.ui.doubleSpinBox_bandPassHigh.value() Config["Filter"]["BandPassHigh"] = self.ui.doubleSpinBox_bandPassHigh.value()
Config["PeaksValue"] = self.ui.spinBox_peaksValue.value() Config["PeaksValue"] = self.ui.spinBox_peaksValue.value()
@ -260,7 +250,6 @@ class MainWindow_detect_Jpeak(QMainWindow):
Config["DetectMethod"] = self.ui.comboBox_model.currentText() Config["DetectMethod"] = self.ui.comboBox_model.currentText()
def __slot_btn_input__(self): def __slot_btn_input__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 清空画框 # 清空画框
@ -300,7 +289,6 @@ class MainWindow_detect_Jpeak(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_view__(self): def __slot_btn_view__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 数据预处理 # 数据预处理
@ -348,7 +336,6 @@ class MainWindow_detect_Jpeak(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_save__(self): def __slot_btn_save__(self):
reply = QMessageBox.question(self, Constants.QUESTION_TITLE, reply = QMessageBox.question(self, Constants.QUESTION_TITLE,
Constants.QUESTION_CONTENT + Config["Path"]["Save"], Constants.QUESTION_CONTENT + Config["Path"]["Save"],
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes | QMessageBox.No,
@ -382,13 +369,11 @@ class MainWindow_detect_Jpeak(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def reset_axes(self): def reset_axes(self):
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
def update_ui_comboBox_model(self, model_list): def update_ui_comboBox_model(self, model_list):
self.ui.comboBox_model.clear() self.ui.comboBox_model.clear()
self.ui.comboBox_model.addItems(model_list) self.ui.comboBox_model.addItems(model_list)
@ -396,31 +381,25 @@ class MainWindow_detect_Jpeak(QMainWindow):
class Data: class Data:
def __init__(self): def __init__(self):
self.file_path_input = Config["Path"]["Input"]
self.file_path_save = Config["Path"]["Save"]
self.raw_data = None self.raw_data = None
self.processed_data = None self.processed_data = None
self.peak = None self.peak = None
self.interval = None self.interval = None
def open_file(self): def open_file(self):
if not Path(Config["Path"]["Input"]).exists(): if not Path(Config["Path"]["Input"]).exists():
return False, Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Data_Path_Not_Exist"] return False, Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Data_Path_Not_Exist"]
try: try:
self.raw_data = read_csv(self.file_path_input, self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception: except Exception:
return False, Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Read_Data_Exception"] return False, Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Read_Data_Exception"]
return True, Constants.INPUT_FINISHED return True, Constants.INPUT_FINISHED
def preprocess(self): def preprocess(self):
if self.raw_data is None: if self.raw_data is None:
return False, Constants.DETECT_JPEAK_PROCESS_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Raw_Data_Not_Exist"] return False, Constants.DETECT_JPEAK_PROCESS_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Raw_Data_Not_Exist"]
@ -436,7 +415,6 @@ class Data:
return True, Constants.DETECT_JPEAK_PROCESS_FINISHED return True, Constants.DETECT_JPEAK_PROCESS_FINISHED
def predict_Jpeak(self, model): def predict_Jpeak(self, model):
if not (Path(model.model_folder_path) / Path(model.selected_model)).exists(): if not (Path(model.model_folder_path) / Path(model.selected_model)).exists():
return False, Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_File_Not_Exist"] return False, Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_File_Not_Exist"]
@ -458,12 +436,11 @@ class Data:
return True, Constants.DETECT_JPEAK_PREDICT_FINISHED return True, Constants.DETECT_JPEAK_PREDICT_FINISHED
def save(self, chunk): def save(self, chunk):
if self.peak is None: if self.peak is None:
return False, Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Peak_Not_Exist"] return False, Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Peak_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save, mode='a', index=False, header=False) chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False)
except Exception: except Exception:
return False, Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Save_Exception"] return False, Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Save_Exception"]
@ -473,14 +450,12 @@ class Data:
class Model: class Model:
def __init__(self): def __init__(self):
self.model_folder_path = Config["ModelFolderPath"] self.model_folder_path = Config["ModelFolderPath"]
self.model_list = None self.model_list = None
self.selected_model_path = None self.selected_model_path = None
self.selected_model = None self.selected_model = None
def seek_model(self): def seek_model(self):
if not Path(Config["ModelFolderPath"]).exists(): if not Path(Config["ModelFolderPath"]).exists():
return False, Constants.DETECT_JPEAK_LOAD_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_Path_Not_Exist"] return False, Constants.DETECT_JPEAK_LOAD_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_Path_Not_Exist"]

View File

@ -41,7 +41,6 @@ ButtonState = {
class SettingWindow(QMainWindow): class SettingWindow(QMainWindow):
def __init__(self, root_path, sampID): def __init__(self, root_path, sampID):
super(SettingWindow, self).__init__() super(SettingWindow, self).__init__()
self.ui = Ui_MainWindow_detect_Rpeak_input_setting() self.ui = Ui_MainWindow_detect_Rpeak_input_setting()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -58,7 +57,6 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH).exists(): if not Path(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH).exists():
with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f: with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.DETECT_RPEAK_CONFIG_NEW_CONTENT, f) dump(ConfigParams.DETECT_RPEAK_CONFIG_NEW_CONTENT, f)
@ -86,7 +84,6 @@ class SettingWindow(QMainWindow):
self.ui.plainTextEdit_file_path_save.setPlainText(Config["Path"]["Save"]) self.ui.plainTextEdit_file_path_save.setPlainText(Config["Path"]["Save"])
def __write_config__(self): def __write_config__(self):
# 从界面写入配置 # 从界面写入配置
Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value() Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
Config["Path"]["Input"] = self.ui.plainTextEdit_file_path_input.toPlainText() Config["Path"]["Input"] = self.ui.plainTextEdit_file_path_input.toPlainText()
@ -101,11 +98,9 @@ class SettingWindow(QMainWindow):
self.close() self.close()
def __rollback_config__(self): def __rollback_config__(self):
self.__read_config__() self.__read_config__()
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input.setPlainText( self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / ConfigParams.PUBLIC_PATH_PSG_TEXT /
@ -118,7 +113,6 @@ class SettingWindow(QMainWindow):
class MainWindow_detect_Rpeak(QMainWindow): class MainWindow_detect_Rpeak(QMainWindow):
def __init__(self): def __init__(self):
super(MainWindow_detect_Rpeak, self).__init__() super(MainWindow_detect_Rpeak, self).__init__()
self.ui = Ui_MainWindow_detect_Rpeak() self.ui = Ui_MainWindow_detect_Rpeak()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -147,7 +141,6 @@ class MainWindow_detect_Rpeak(QMainWindow):
@overrides @overrides
def show(self, root_path, sampID): def show(self, root_path, sampID):
super().show() super().show()
self.root_path = root_path self.root_path = root_path
self.sampID = sampID self.sampID = sampID
@ -190,7 +183,6 @@ class MainWindow_detect_Rpeak(QMainWindow):
@overrides @overrides
def closeEvent(self, event): def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN)) PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
@ -211,12 +203,10 @@ class MainWindow_detect_Rpeak(QMainWindow):
@staticmethod @staticmethod
def __reset__(): def __reset__():
ButtonState["Current"].update(ButtonState["Default"].copy()) ButtonState["Current"].update(ButtonState["Default"].copy())
ButtonState["Current"]["pushButton_view"] = True ButtonState["Current"]["pushButton_view"] = True
def __plot__(self): def __plot__(self):
# 清空画框 # 清空画框
self.reset_axes() self.reset_axes()
@ -247,14 +237,12 @@ class MainWindow_detect_Rpeak(QMainWindow):
return status, info return status, info
def __update_config__(self): def __update_config__(self):
Config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value() Config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value()
Config["Filter"]["BandPassHigh"] = self.ui.doubleSpinBox_bandPassHigh.value() Config["Filter"]["BandPassHigh"] = self.ui.doubleSpinBox_bandPassHigh.value()
Config["PeaksValue"] = self.ui.spinBox_peaksValue.value() Config["PeaksValue"] = self.ui.spinBox_peaksValue.value()
Config["DetectMethod"] = self.ui.comboBox_method.currentText() Config["DetectMethod"] = self.ui.comboBox_method.currentText()
def __slot_btn_input__(self): def __slot_btn_input__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 清空画框 # 清空画框
@ -300,7 +288,6 @@ class MainWindow_detect_Rpeak(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_view__(self): def __slot_btn_view__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 数据预处理 # 数据预处理
@ -347,7 +334,6 @@ class MainWindow_detect_Rpeak(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_save__(self): def __slot_btn_save__(self):
reply = QMessageBox.question(self, Constants.QUESTION_TITLE, reply = QMessageBox.question(self, Constants.QUESTION_TITLE,
Constants.QUESTION_CONTENT + Config["Path"]["Save"], Constants.QUESTION_CONTENT + Config["Path"]["Save"],
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes | QMessageBox.No,
@ -381,7 +367,6 @@ class MainWindow_detect_Rpeak(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def reset_axes(self): def reset_axes(self):
self.ax0.clear() self.ax0.clear()
self.ax1.clear() self.ax1.clear()
self.ax0.grid(True) self.ax0.grid(True)
@ -391,7 +376,6 @@ class MainWindow_detect_Rpeak(QMainWindow):
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
def update_ui_comboBox_method(self, method_list): def update_ui_comboBox_method(self, method_list):
self.ui.comboBox_method.clear() self.ui.comboBox_method.clear()
self.ui.comboBox_method.addItems(method_list) self.ui.comboBox_method.addItems(method_list)
@ -399,9 +383,6 @@ class MainWindow_detect_Rpeak(QMainWindow):
class Data: class Data:
def __init__(self): def __init__(self):
self.file_path_input = Config["Path"]["Input"]
self.file_path_save = Config["Path"]["Save"]
self.raw_data = None self.raw_data = None
self.processed_data = None self.processed_data = None
self.peak = None self.peak = None
@ -409,21 +390,19 @@ class Data:
self.RRIV = None self.RRIV = None
def open_file(self): def open_file(self):
if not Path(Config["Path"]["Input"]).exists(): if not Path(Config["Path"]["Input"]).exists():
return False, Constants.INPUT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Data_Path_Not_Exist"] return False, Constants.INPUT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Data_Path_Not_Exist"]
try: try:
self.raw_data = read_csv(self.file_path_input, self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception: except Exception:
return False, Constants.INPUT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Read_Data_Exception"] return False, Constants.INPUT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Read_Data_Exception"]
return True, Constants.INPUT_FINISHED return True, Constants.INPUT_FINISHED
def preprocess(self): def preprocess(self):
if self.raw_data is None: if self.raw_data is None:
return False, Constants.DETECT_RPEAK_PROCESS_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Raw_Data_Not_Exist"] return False, Constants.DETECT_RPEAK_PROCESS_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Raw_Data_Not_Exist"]
@ -438,7 +417,6 @@ class Data:
return True, Constants.DETECT_RPEAK_PROCESS_FINISHED return True, Constants.DETECT_RPEAK_PROCESS_FINISHED
def predict_Rpeak(self): def predict_Rpeak(self):
if self.processed_data is None: if self.processed_data is None:
return False, Constants.DETECT_RPEAK_PREDICT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Processed_Data_Not_Exist"] return False, Constants.DETECT_RPEAK_PREDICT_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Processed_Data_Not_Exist"]
@ -453,12 +431,11 @@ class Data:
return True, Constants.DETECT_RPEAK_PREDICT_FINISHED return True, Constants.DETECT_RPEAK_PREDICT_FINISHED
def save(self, chunk): def save(self, chunk):
if self.peak is None: if self.peak is None:
return False, Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Peak_Not_Exist"] return False, Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Peak_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save, mode='a', index=False, header=False) chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False)
except Exception: except Exception:
return False, Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Save_Exception"] return False, Constants.SAVING_FAILURE + Constants.DETECT_RPEAK_FAILURE_REASON["Save_Exception"]

View File

@ -49,7 +49,6 @@ ButtonState = {
class SettingWindow(QMainWindow): class SettingWindow(QMainWindow):
def __init__(self, mode, root_path, sampID): def __init__(self, mode, root_path, sampID):
super(SettingWindow, self).__init__() super(SettingWindow, self).__init__()
self.ui = Ui_MainWindow_label_check_input_setting() self.ui = Ui_MainWindow_label_check_input_setting()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -70,7 +69,6 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH).exists(): if not Path(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH).exists():
with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f: with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.LABEL_CHECK_CONFIG_NEW_CONTENT, f) dump(ConfigParams.LABEL_CHECK_CONFIG_NEW_CONTENT, f)
@ -132,7 +130,6 @@ class SettingWindow(QMainWindow):
raise ValueError("模式不存在") raise ValueError("模式不存在")
def __write_config__(self): def __write_config__(self):
# 从界面写入配置 # 从界面写入配置
Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq_signal.value() Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq_signal.value()
Config["Path"]["Input_Signal"] = self.ui.plainTextEdit_file_path_input_signal.toPlainText() Config["Path"]["Input_Signal"] = self.ui.plainTextEdit_file_path_input_signal.toPlainText()
@ -158,11 +155,9 @@ class SettingWindow(QMainWindow):
self.close() self.close()
def __rollback_config__(self): def __rollback_config__(self):
self.__read_config__() self.__read_config__()
def __update_ui__(self): def __update_ui__(self):
if self.mode == "BCG": if self.mode == "BCG":
self.ui.plainTextEdit_file_path_input_signal.setPlainText( self.ui.plainTextEdit_file_path_input_signal.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
@ -186,7 +181,6 @@ class SettingWindow(QMainWindow):
class MainWindow_label_check(QMainWindow): class MainWindow_label_check(QMainWindow):
def __init__(self): def __init__(self):
super(MainWindow_label_check, self).__init__() super(MainWindow_label_check, self).__init__()
self.ui = Ui_MainWindow_label_check() self.ui = Ui_MainWindow_label_check()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -236,7 +230,6 @@ class MainWindow_label_check(QMainWindow):
@overrides @overrides
def show(self, mode, root_path, sampID): def show(self, mode, root_path, sampID):
super().show() super().show()
self.mode = mode self.mode = mode
self.root_path = root_path self.root_path = root_path
@ -307,7 +300,6 @@ class MainWindow_label_check(QMainWindow):
@overrides @overrides
def closeEvent(self, event): def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN)) PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
@ -331,11 +323,9 @@ class MainWindow_label_check(QMainWindow):
@staticmethod @staticmethod
def __reset__(): def __reset__():
ButtonState["Current"].update(ButtonState["Default"].copy()) ButtonState["Current"].update(ButtonState["Default"].copy())
def __plot__(self): def __plot__(self):
# 清空画框 # 清空画框
if self.point_peak_original is not None: if self.point_peak_original is not None:
self.point_peak_original.remove() self.point_peak_original.remove()
@ -373,7 +363,6 @@ class MainWindow_label_check(QMainWindow):
return status, info return status, info
def __plot_peaks__(self): def __plot_peaks__(self):
try: try:
self.point_peak_original, = self.ax0.plot(self.data.original_peak, self.data.original_peak_y, 'ro', self.point_peak_original, = self.ax0.plot(self.data.original_peak, self.data.original_peak_y, 'ro',
label=Constants.LABEL_CHECK_PLOT_LABEL_PEAK_ORIGINAL) label=Constants.LABEL_CHECK_PLOT_LABEL_PEAK_ORIGINAL)
@ -389,14 +378,12 @@ class MainWindow_label_check(QMainWindow):
return True, Constants.DRAWING_FINISHED return True, Constants.DRAWING_FINISHED
def __redraw_peaks__(self): def __redraw_peaks__(self):
self.point_peak_corrected.remove() self.point_peak_corrected.remove()
self.point_peak_corrected, = self.ax1.plot(self.data.corrected_peak, self.data.corrected_peak_y, 'ro', self.point_peak_corrected, = self.ax1.plot(self.data.corrected_peak, self.data.corrected_peak_y, 'ro',
label=Constants.LABEL_CHECK_PLOT_LABEL_PEAK_CORRECTED) label=Constants.LABEL_CHECK_PLOT_LABEL_PEAK_CORRECTED)
self.canvas.draw() self.canvas.draw()
def __update_tableWidget_and_info__(self): def __update_tableWidget_and_info__(self):
if self.data.original_peak is None or self.data.corrected_peak is None: if self.data.original_peak is None or self.data.corrected_peak is None:
return False, Constants.LABEL_CHECK_FAILURE_REASON["Peak_Not_Exist"] return False, Constants.LABEL_CHECK_FAILURE_REASON["Peak_Not_Exist"]
@ -419,7 +406,6 @@ class MainWindow_label_check(QMainWindow):
return status, info return status, info
def __update_config__(self): def __update_config__(self):
Config["FindPeaks"]["MinInterval"] = self.ui.doubleSpinBox_findpeaks_min_interval.value() Config["FindPeaks"]["MinInterval"] = self.ui.doubleSpinBox_findpeaks_min_interval.value()
Config["FindPeaks"]["MinHeight"] = self.ui.doubleSpinBox_findpeaks_min_height.value() Config["FindPeaks"]["MinHeight"] = self.ui.doubleSpinBox_findpeaks_min_height.value()
Config["CustomAutoplayArgs"]["MoveLength"] = self.ui.spinBox_moveLength.value() Config["CustomAutoplayArgs"]["MoveLength"] = self.ui.spinBox_moveLength.value()
@ -427,7 +413,6 @@ class MainWindow_label_check(QMainWindow):
Config["CustomAutoplayArgs"]["MoveSpeed"] = self.ui.spinBox_moveSpeed.value() Config["CustomAutoplayArgs"]["MoveSpeed"] = self.ui.spinBox_moveSpeed.value()
def __slot_btn_input__(self): def __slot_btn_input__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 清空画框 # 清空画框
@ -526,7 +511,6 @@ class MainWindow_label_check(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_save__(self): def __slot_btn_save__(self):
reply = QMessageBox.question(self, Constants.QUESTION_TITLE, reply = QMessageBox.question(self, Constants.QUESTION_TITLE,
Constants.QUESTION_CONTENT + Config["Path"]["Save"], Constants.QUESTION_CONTENT + Config["Path"]["Save"],
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes | QMessageBox.No,
@ -560,7 +544,6 @@ class MainWindow_label_check(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_move__(self): def __slot_btn_move__(self):
if self.data is None: if self.data is None:
return return
@ -594,7 +577,6 @@ class MainWindow_label_check(QMainWindow):
PublicFunc.text_output(self.ui, Constants.LABEL_CHECK_PAUSE, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, Constants.LABEL_CHECK_PAUSE, Constants.TIPS_TYPE_INFO)
def __change_autoplay_args__(self): def __change_autoplay_args__(self):
sender = self.sender() sender = self.sender()
if sender == self.ui.radioButton_move_preset_1 and self.ui.radioButton_move_preset_1.isChecked(): if sender == self.ui.radioButton_move_preset_1 and self.ui.radioButton_move_preset_1.isChecked():
@ -637,7 +619,6 @@ class MainWindow_label_check(QMainWindow):
self.timer_autoplay.stop() self.timer_autoplay.stop()
def __slot_tableWidget_on_cell_double_clicked__(self, row, col): def __slot_tableWidget_on_cell_double_clicked__(self, row, col):
if Config["AutoplayArgs"]["AutoplayMode"] != "pause": if Config["AutoplayArgs"]["AutoplayMode"] != "pause":
self.ui.pushButton_pause.click() self.ui.pushButton_pause.click()
@ -657,7 +638,6 @@ class MainWindow_label_check(QMainWindow):
PublicFunc.text_output(self.ui, f"{Constants.LABEL_CHECK_JUMP_X_INDEX}{str(int(x))}", Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, f"{Constants.LABEL_CHECK_JUMP_X_INDEX}{str(int(x))}", Constants.TIPS_TYPE_INFO)
def reset_axes(self): def reset_axes(self):
self.ax0.clear() self.ax0.clear()
self.ax1.clear() self.ax1.clear()
self.ax0.grid(True) self.ax0.grid(True)
@ -667,7 +647,6 @@ class MainWindow_label_check(QMainWindow):
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
def on_xlim_change(self, event_ax): def on_xlim_change(self, event_ax):
try: try:
if self.annotation_tableWidget is not None: if self.annotation_tableWidget is not None:
self.annotation_tableWidget.remove() self.annotation_tableWidget.remove()
@ -676,7 +655,6 @@ class MainWindow_label_check(QMainWindow):
pass pass
def autoplay_move_xlim(self): def autoplay_move_xlim(self):
if Config["AutoplayArgs"]["AutoplayMode"] == "prev" and self.autoplay_xlim_start < 0: if Config["AutoplayArgs"]["AutoplayMode"] == "prev" and self.autoplay_xlim_start < 0:
Config["AutoplayArgs"]["AutoplayMode"] = "pause" Config["AutoplayArgs"]["AutoplayMode"] = "pause"
self.timer_autoplay.stop() self.timer_autoplay.stop()
@ -694,7 +672,6 @@ class MainWindow_label_check(QMainWindow):
self.canvas.draw() self.canvas.draw()
def on_motion(self, event): def on_motion(self, event):
if event.inaxes and self.ui.checkBox_show_reference_line.isChecked(): if event.inaxes and self.ui.checkBox_show_reference_line.isChecked():
# Clear previous reference lines and temporary points # Clear previous reference lines and temporary points
for line in self.ax0.lines[1:]: for line in self.ax0.lines[1:]:
@ -715,7 +692,6 @@ class MainWindow_label_check(QMainWindow):
self.canvas.draw() self.canvas.draw()
def toggle_home(self): def toggle_home(self):
if Config["AutoplayArgs"]["AutoplayMode"] != "pause": if Config["AutoplayArgs"]["AutoplayMode"] != "pause":
self.ui.pushButton_pause.click() self.ui.pushButton_pause.click()
self.ax0.autoscale(True) self.ax0.autoscale(True)
@ -728,7 +704,6 @@ class MainWindow_label_check(QMainWindow):
PublicFunc.text_output(self.ui, Constants.LABEL_CHECK_RECOVER_SCALE, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, Constants.LABEL_CHECK_RECOVER_SCALE, Constants.TIPS_TYPE_INFO)
def toggle_changeLabel(self, state): def toggle_changeLabel(self, state):
if state: if state:
self.deactivate_figToolbar_buttons() self.deactivate_figToolbar_buttons()
self.figToolbar.action_Label_Multiple.setChecked(True) self.figToolbar.action_Label_Multiple.setChecked(True)
@ -750,7 +725,6 @@ class MainWindow_label_check(QMainWindow):
self.figToolbar.cid_mouse_hold = None self.figToolbar.cid_mouse_hold = None
def deactivate_figToolbar_buttons(self): def deactivate_figToolbar_buttons(self):
for action in self.figToolbar._actions.values(): for action in self.figToolbar._actions.values():
if action.isChecked() == True: if action.isChecked() == True:
if action == self.figToolbar._actions['pan']: if action == self.figToolbar._actions['pan']:
@ -759,7 +733,6 @@ class MainWindow_label_check(QMainWindow):
self.figToolbar.zoom() self.figToolbar.zoom()
def on_click(self, event): def on_click(self, event):
if self.figToolbar.action_Label_Multiple.isChecked(): if self.figToolbar.action_Label_Multiple.isChecked():
if event.button == 1 or event.button == 3: # 左键或右键 if event.button == 1 or event.button == 3: # 左键或右键
if event.button == 1: if event.button == 1:
@ -776,7 +749,6 @@ class MainWindow_label_check(QMainWindow):
self.canvas.draw() self.canvas.draw()
def on_release(self, event): def on_release(self, event):
if self.figToolbar.action_Label_Multiple.isChecked(): if self.figToolbar.action_Label_Multiple.isChecked():
if self.figToolbar.rect_start_x is not None: if self.figToolbar.rect_start_x is not None:
self.figToolbar.rect_end_x = event.xdata self.figToolbar.rect_end_x = event.xdata
@ -839,8 +811,7 @@ class MainWindow_label_check(QMainWindow):
self.data.corrected_peak.sort() self.data.corrected_peak.sort()
self.data.corrected_peak_y = [self.data.processed_data[x] for x in self.data.corrected_peak] self.data.corrected_peak_y = [self.data.processed_data[x] for x in self.data.corrected_peak]
self.__update_tableWidget_and_info__() self.__update_tableWidget_and_info__()
DataFrame(self.data.corrected_peak).to_csv(self.data.file_path_save, DataFrame(self.data.corrected_peak).to_csv(Config["Path"]["Save"], index=False, header=False)
index=False, header=False)
# 移除矩形patch # 移除矩形patch
if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None: if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None:
self.figToolbar.rect_patch_ax0.remove() self.figToolbar.rect_patch_ax0.remove()
@ -850,7 +821,6 @@ class MainWindow_label_check(QMainWindow):
self.canvas.draw() self.canvas.draw()
def on_hold(self, event): def on_hold(self, event):
if self.figToolbar.rect_start_x is not None and event.xdata is not None: if self.figToolbar.rect_start_x is not None and event.xdata is not None:
self.figToolbar.rect_end_x = event.xdata self.figToolbar.rect_end_x = event.xdata
@ -896,10 +866,6 @@ class MainWindow_label_check(QMainWindow):
class Data: class Data:
def __init__(self): def __init__(self):
self.file_path_input_signal = Config["Path"]["Input_Signal"]
self.file_path_input_peak = Config["Path"]["Input_Peak"]
self.file_path_save = Config["Path"]["Save"]
self.raw_data = None self.raw_data = None
self.processed_data = None self.processed_data = None
self.original_peak = None self.original_peak = None
@ -908,15 +874,14 @@ class Data:
self.corrected_peak_y = None self.corrected_peak_y = None
def open_file(self): def open_file(self):
if (not Path(Config["Path"]["Input_Signal"]).exists()) or (not Path(Config["Path"]["Input_Peak"]).exists()): if (not Path(Config["Path"]["Input_Signal"]).exists()) or (not Path(Config["Path"]["Input_Peak"]).exists()):
return False, Constants.INPUT_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Data_Path_Not_Exist"] return False, Constants.INPUT_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Data_Path_Not_Exist"]
try: try:
self.raw_data = read_csv(self.file_path_input_signal, self.raw_data = read_csv(Config["Path"]["Input_Signal"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.original_peak = read_csv(self.file_path_input_peak, self.original_peak = read_csv(Config["Path"]["Input_Peak"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception: except Exception:
@ -925,18 +890,16 @@ class Data:
return True, Constants.INPUT_FINISHED return True, Constants.INPUT_FINISHED
def get_archive(self): def get_archive(self):
if not Path(Config["Path"]["Save"]).exists(): if not Path(Config["Path"]["Save"]).exists():
self.corrected_peak = self.original_peak self.corrected_peak = self.original_peak
return True, Constants.LABEL_CHECK_ARCHIVE_NOT_EXIST return True, Constants.LABEL_CHECK_ARCHIVE_NOT_EXIST
else: else:
self.corrected_peak = read_csv(self.file_path_save, self.corrected_peak = read_csv(Config["Path"]["Save"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
return True, Constants.LABEL_CHECK_ARCHIVE_EXIST return True, Constants.LABEL_CHECK_ARCHIVE_EXIST
def preprocess(self): def preprocess(self):
if self.raw_data is None: if self.raw_data is None:
return False, Constants.LABEL_CHECK_PROCESS_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Raw_Data_Not_Exist"] return False, Constants.LABEL_CHECK_PROCESS_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Raw_Data_Not_Exist"]
@ -963,12 +926,11 @@ class Data:
return True, Constants.LABEL_CHECK_PROCESS_FINISHED return True, Constants.LABEL_CHECK_PROCESS_FINISHED
def save(self, chunk): def save(self, chunk):
if self.corrected_peak is None: if self.corrected_peak is None:
return False, Constants.SAVING_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Peak_Not_Exist"] return False, Constants.SAVING_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Peak_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save, mode='a', index=False, header=False) chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False)
except Exception: except Exception:
return False, Constants.SAVING_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Save_Exception"] return False, Constants.SAVING_FAILURE + Constants.LABEL_CHECK_FAILURE_REASON["Save_Exception"]
@ -1007,21 +969,17 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
self.rect_patch_ax1 = None # 用于绘制矩形的patch self.rect_patch_ax1 = None # 用于绘制矩形的patch
def home(self, *args): def home(self, *args):
pass pass
def zoom(self, *args): def zoom(self, *args):
super().zoom(*args) super().zoom(*args)
self.deactivate_figToorbar_changeLabel_mode() self.deactivate_figToorbar_changeLabel_mode()
def pan(self, *args): def pan(self, *args):
super().pan(*args) super().pan(*args)
self.deactivate_figToorbar_changeLabel_mode() self.deactivate_figToorbar_changeLabel_mode()
def deactivate_figToorbar_changeLabel_mode(self): def deactivate_figToorbar_changeLabel_mode(self):
if self.action_Label_Multiple.isChecked(): if self.action_Label_Multiple.isChecked():
self.action_Label_Multiple.setChecked(False) self.action_Label_Multiple.setChecked(False)
if self.cid_mouse_press is not None: if self.cid_mouse_press is not None:

View File

@ -12,6 +12,7 @@ from func.Module_detect_Jpeak import MainWindow_detect_Jpeak
from func.Module_detect_Rpeak import MainWindow_detect_Rpeak from func.Module_detect_Rpeak import MainWindow_detect_Rpeak
from func.Module_label_check import MainWindow_label_check from func.Module_label_check import MainWindow_label_check
from func.Module_precisely_align import MainWindow_precisely_align from func.Module_precisely_align import MainWindow_precisely_align
from func.Module_cut_PSG import MainWindow_cut_PSG
from func.utils.Constants import Constants, ConfigParams from func.utils.Constants import Constants, ConfigParams
@ -27,7 +28,6 @@ Config = {
class MainWindow(QMainWindow, Ui_Signal_Label): class MainWindow(QMainWindow, Ui_Signal_Label):
def __init__(self): def __init__(self):
super(MainWindow, self).__init__() super(MainWindow, self).__init__()
self.ui = Ui_Signal_Label() self.ui = Ui_Signal_Label()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -45,6 +45,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.detect_Rpeak = None self.detect_Rpeak = None
self.label_check = None self.label_check = None
self.precisely_align = None self.precisely_align = None
self.cut_PSG = None
# 绑定槽函数 # 绑定槽函数
self.ui.pushButton_open.clicked.connect(self.__slot_btn_open__) self.ui.pushButton_open.clicked.connect(self.__slot_btn_open__)
@ -55,10 +56,10 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.ui.pushButton_label_check_BCG.clicked.connect(self.__slot_btn_label_check__) self.ui.pushButton_label_check_BCG.clicked.connect(self.__slot_btn_label_check__)
self.ui.pushButton_label_check_ECG.clicked.connect(self.__slot_btn_label_check__) self.ui.pushButton_label_check_ECG.clicked.connect(self.__slot_btn_label_check__)
self.ui.pushButton_precisely_align.clicked.connect(self.__slot_btn_precisely_align__) self.ui.pushButton_precisely_align.clicked.connect(self.__slot_btn_precisely_align__)
self.ui.pushButton_cut_PSG.clicked.connect(self.__slot_btn_cut_PSG__)
@staticmethod @staticmethod
def __read_config__(): def __read_config__():
if not Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).exists(): if not Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).exists():
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "w") as f: with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PUBLIC_CONFIG_NEW_CONTENT, f) dump(ConfigParams.PUBLIC_CONFIG_NEW_CONTENT, f)
@ -69,12 +70,10 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
@staticmethod @staticmethod
def __write_config__(): def __write_config__():
with open(Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH), "w") as f: with open(Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH), "w") as f:
dump(Config, f) dump(Config, f)
def __slot_btn_open__(self): def __slot_btn_open__(self):
file_dialog = QFileDialog() file_dialog = QFileDialog()
file_dialog.setFileMode(QFileDialog.Directory) file_dialog.setFileMode(QFileDialog.Directory)
file_dialog.setOption(QFileDialog.ShowDirsOnly, True) file_dialog.setOption(QFileDialog.ShowDirsOnly, True)
@ -89,7 +88,6 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
PublicFunc.msgbox_output(self, Constants.OPERATION_CANCELED, Constants.MSGBOX_TYPE_INFO) PublicFunc.msgbox_output(self, Constants.OPERATION_CANCELED, Constants.MSGBOX_TYPE_INFO)
def __slot_btn_preprocess__(self): def __slot_btn_preprocess__(self):
self.preprocess = MainWindow_preprocess() self.preprocess = MainWindow_preprocess()
sender = self.sender() sender = self.sender()
@ -104,21 +102,18 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.preprocess.show(mode, root_path, sampID) self.preprocess.show(mode, root_path, sampID)
def __slot_btn_detect_Jpeak__(self): def __slot_btn_detect_Jpeak__(self):
self.detect_Jpeak = MainWindow_detect_Jpeak() self.detect_Jpeak = MainWindow_detect_Jpeak()
root_path = self.ui.plainTextEdit_root_path.toPlainText() root_path = self.ui.plainTextEdit_root_path.toPlainText()
sampID = int(self.ui.comboBox_sampID.currentText()) sampID = int(self.ui.comboBox_sampID.currentText())
self.detect_Jpeak.show(root_path, sampID) self.detect_Jpeak.show(root_path, sampID)
def __slot_btn_detect_Rpeak__(self): def __slot_btn_detect_Rpeak__(self):
self.detect_Rpeak = MainWindow_detect_Rpeak() self.detect_Rpeak = MainWindow_detect_Rpeak()
root_path = self.ui.plainTextEdit_root_path.toPlainText() root_path = self.ui.plainTextEdit_root_path.toPlainText()
sampID = int(self.ui.comboBox_sampID.currentText()) sampID = int(self.ui.comboBox_sampID.currentText())
self.detect_Rpeak.show(root_path, sampID) self.detect_Rpeak.show(root_path, sampID)
def __slot_btn_label_check__(self): def __slot_btn_label_check__(self):
self.label_check = MainWindow_label_check() self.label_check = MainWindow_label_check()
sender = self.sender() sender = self.sender()
@ -133,14 +128,18 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.label_check.show(mode, root_path, sampID) self.label_check.show(mode, root_path, sampID)
def __slot_btn_precisely_align__(self): def __slot_btn_precisely_align__(self):
self.precisely_align = MainWindow_precisely_align() self.precisely_align = MainWindow_precisely_align()
root_path = self.ui.plainTextEdit_root_path.toPlainText() root_path = self.ui.plainTextEdit_root_path.toPlainText()
sampID = int(self.ui.comboBox_sampID.currentText()) sampID = int(self.ui.comboBox_sampID.currentText())
self.precisely_align.show(root_path, sampID) self.precisely_align.show(root_path, sampID)
def seek_sampID(self, path): def __slot_btn_cut_PSG__(self):
self.cut_PSG = MainWindow_cut_PSG()
root_path = self.ui.plainTextEdit_root_path.toPlainText()
sampID = int(self.ui.comboBox_sampID.currentText())
self.cut_PSG.show(root_path, sampID)
def seek_sampID(self, path):
if not Path(path).exists(): if not Path(path).exists():
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR)
return return

View File

@ -82,7 +82,6 @@ ButtonState = {
class SettingWindow(QMainWindow): class SettingWindow(QMainWindow):
def __init__(self, root_path, sampID): def __init__(self, root_path, sampID):
super(SettingWindow, self).__init__() super(SettingWindow, self).__init__()
self.ui = Ui_MainWindow_precisely_align_input_setting() self.ui = Ui_MainWindow_precisely_align_input_setting()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -99,7 +98,6 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH).exists(): if not Path(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH).exists():
with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f: with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PRECISELY_ALIGN_CONFIG_NEW_CONTENT, f) dump(ConfigParams.PRECISELY_ALIGN_CONFIG_NEW_CONTENT, f)
@ -213,7 +211,6 @@ class SettingWindow(QMainWindow):
self.ui.plainTextEdit_file_path_save_Rpeak.setPlainText(Config["Path"]["Save_Rpeak"]) self.ui.plainTextEdit_file_path_save_Rpeak.setPlainText(Config["Path"]["Save_Rpeak"])
def __write_config__(self): def __write_config__(self):
# 从界面写入配置 # 从界面写入配置
Config["InputConfig"]["ECGFreq"] = self.ui.spinBox_input_freq_ECG.value() Config["InputConfig"]["ECGFreq"] = self.ui.spinBox_input_freq_ECG.value()
Config["Path"]["Input_orgBcg"] = self.ui.plainTextEdit_file_path_input_orgBcg.toPlainText() Config["Path"]["Input_orgBcg"] = self.ui.plainTextEdit_file_path_input_orgBcg.toPlainText()
@ -238,11 +235,9 @@ class SettingWindow(QMainWindow):
self.close() self.close()
def __rollback_config__(self): def __rollback_config__(self):
self.__read_config__() self.__read_config__()
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText( self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
@ -302,7 +297,6 @@ class SettingWindow(QMainWindow):
class MainWindow_precisely_align(QMainWindow): class MainWindow_precisely_align(QMainWindow):
def __init__(self): def __init__(self):
super(MainWindow_precisely_align, self).__init__() super(MainWindow_precisely_align, self).__init__()
self.ui = Ui_MainWindow_precisely_align() self.ui = Ui_MainWindow_precisely_align()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -356,7 +350,6 @@ class MainWindow_precisely_align(QMainWindow):
@overrides @overrides
def show(self, root_path, sampID): def show(self, root_path, sampID):
super().show() super().show()
self.root_path = root_path self.root_path = root_path
self.sampID = sampID self.sampID = sampID
@ -408,7 +401,6 @@ class MainWindow_precisely_align(QMainWindow):
@overrides @overrides
def closeEvent(self, event): def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN)) PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
@ -449,11 +441,9 @@ class MainWindow_precisely_align(QMainWindow):
@staticmethod @staticmethod
def __reset__(): def __reset__():
ButtonState["Current"].update(ButtonState["Default"].copy()) ButtonState["Current"].update(ButtonState["Default"].copy())
def __plot__(self, plot_element=None): def __plot__(self, plot_element=None):
# 清空画框 # 清空画框
if self.figToolbar.ax0_BCG_rectangle_front is not None: if self.figToolbar.ax0_BCG_rectangle_front is not None:
self.figToolbar.ax0_BCG_rectangle_front.remove() self.figToolbar.ax0_BCG_rectangle_front.remove()
@ -526,11 +516,11 @@ class MainWindow_precisely_align(QMainWindow):
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT)
self.ax0.plot(plot_element["front"]["corre"], 'o', color=Constants.PLOT_COLOR_BLUE, self.ax0.plot(plot_element["front"]["corre"], 'o', color=Constants.PLOT_COLOR_BLUE,
markersize=3, picker=True, pickradius=5) markersize=3, picker=True, pickradius=5)
self.ax1.stem(plot_element["front"]["RRIVs"], markerfmt="b.", self.ax1.stem(plot_element["front"]["RRIVs"], markerfmt="b.", linefmt=Constants.PLOT_COLOR_ORANGE,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
self.stem_black0 = self.ax1.stem(arange(plot_element["front"]["shift"], self.stem_black0 = self.ax1.stem(arange(plot_element["front"]["shift"],
plot_element["front"]["shift"] + len(plot_element["front"]["JJIVs"])), plot_element["front"]["shift"] + len(plot_element["front"]["JJIVs"])),
plot_element["front"]["JJIVs"], markerfmt="ko", plot_element["front"]["JJIVs"], markerfmt="ko", linefmt=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
self.ax2.set_title( self.ax2.set_title(
"back\ncorre_IIV: {}, corre_II: {}\nsame_sign_rate:{}, total_time_ratio: {}\nshift: {}, alignment offset: {} seconds\noffset_interval: {}, anchor_J: {}, anchor_R: {}".format( "back\ncorre_IIV: {}, corre_II: {}\nsame_sign_rate:{}, total_time_ratio: {}\nshift: {}, alignment offset: {} seconds\noffset_interval: {}, anchor_J: {}, anchor_R: {}".format(
@ -547,11 +537,11 @@ class MainWindow_precisely_align(QMainWindow):
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT)
self.ax2.plot(plot_element["back"]["corre"], 'o', color=Constants.PLOT_COLOR_BLUE, self.ax2.plot(plot_element["back"]["corre"], 'o', color=Constants.PLOT_COLOR_BLUE,
markersize=3, picker=True, pickradius=5) markersize=3, picker=True, pickradius=5)
self.ax3.stem(plot_element["back"]["RRIVs"], markerfmt="b.", self.ax3.stem(plot_element["back"]["RRIVs"], markerfmt="b.", linefmt=Constants.PLOT_COLOR_ORANGE,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
self.stem_black1 = self.ax3.stem(arange(plot_element["back"]["shift"], self.stem_black1 = self.ax3.stem(arange(plot_element["back"]["shift"],
plot_element["back"]["shift"] + len(plot_element["back"]["JJIVs"])), plot_element["back"]["shift"] + len(plot_element["back"]["JJIVs"])),
plot_element["back"]["JJIVs"], markerfmt="ko", plot_element["back"]["JJIVs"], markerfmt="ko", linefmt=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT) self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
@ -607,7 +597,6 @@ class MainWindow_precisely_align(QMainWindow):
return status, info return status, info
def __update_info__(self): def __update_info__(self):
self.ui.spinBox_BCG_front_JJIV_1.setValue(Config["IV_Coordinate"]["BCG_front_1"]) self.ui.spinBox_BCG_front_JJIV_1.setValue(Config["IV_Coordinate"]["BCG_front_1"])
self.ui.spinBox_BCG_front_JJIV_2.setValue(Config["IV_Coordinate"]["BCG_front_2"]) self.ui.spinBox_BCG_front_JJIV_2.setValue(Config["IV_Coordinate"]["BCG_front_2"])
self.ui.spinBox_BCG_back_JJIV_1.setValue(Config["IV_Coordinate"]["BCG_back_1"]) self.ui.spinBox_BCG_back_JJIV_1.setValue(Config["IV_Coordinate"]["BCG_back_1"])
@ -626,7 +615,6 @@ class MainWindow_precisely_align(QMainWindow):
self.ui.spinBox_ECG_back_Signal_2.setValue(Config["Coordinate"]["ECG_back_2"]) self.ui.spinBox_ECG_back_Signal_2.setValue(Config["Coordinate"]["ECG_back_2"])
def __slot_btn_input__(self): def __slot_btn_input__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 清空画框 # 清空画框
@ -679,7 +667,6 @@ class MainWindow_precisely_align(QMainWindow):
def __slot_btn_calculate_correlation__(self, test1=None, shift_front=None, shift_back=None): 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) PublicFunc.__disableAllButton__(self, ButtonState)
sender = self.sender() sender = self.sender()
@ -740,7 +727,6 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_correlation_align__(self): def __slot_btn_correlation_align__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
sender = self.sender() sender = self.sender()
@ -783,7 +769,6 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_view_align__(self): def __slot_btn_view_align__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 数据后处理 # 数据后处理
@ -812,7 +797,6 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_save__(self): def __slot_btn_save__(self):
reply = QMessageBox.question(self, Constants.QUESTION_TITLE, Constants.QUESTION_CONTENT, reply = QMessageBox.question(self, Constants.QUESTION_TITLE, Constants.QUESTION_CONTENT,
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes) QMessageBox.Yes)
@ -944,7 +928,6 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __update_coordinate__(self): def __update_coordinate__(self):
try: try:
if self.data is not None: if self.data is not None:
if self.data.Jpeak is None or self.data.Rpeak is None: if self.data.Jpeak is None or self.data.Rpeak is None:
@ -1005,7 +988,6 @@ class MainWindow_precisely_align(QMainWindow):
pass pass
def reset_axes(self): def reset_axes(self):
for ax in self.fig.axes: for ax in self.fig.axes:
self.fig.delaxes(ax) self.fig.delaxes(ax)
if self.ax0 is not None: if self.ax0 is not None:
@ -1030,7 +1012,6 @@ class MainWindow_precisely_align(QMainWindow):
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
def redraw_calculate_coordination(self, plot_element=None): def redraw_calculate_coordination(self, plot_element=None):
if plot_element is not None and plot_element["mode"] == "select": if plot_element is not None and plot_element["mode"] == "select":
if self.selected_point0 is not None: if self.selected_point0 is not None:
self.selected_point0.remove() self.selected_point0.remove()
@ -1065,7 +1046,7 @@ class MainWindow_precisely_align(QMainWindow):
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT)
self.stem_black0 = self.ax1.stem(arange(plot_element["front"]["shift"], self.stem_black0 = self.ax1.stem(arange(plot_element["front"]["shift"],
plot_element["front"]["shift"] + len(plot_element["front"]["JJIVs"])), plot_element["front"]["shift"] + len(plot_element["front"]["JJIVs"])),
plot_element["front"]["JJIVs"], markerfmt="ko", plot_element["front"]["JJIVs"], markerfmt="ko", linefmt=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
self.selected_point1, = self.ax2.plot(plot_element["back"]["shift"], self.selected_point1, = self.ax2.plot(plot_element["back"]["shift"],
plot_element["back"]["corre"][plot_element["back"]["shift"]] + 1, 'v', plot_element["back"]["corre"][plot_element["back"]["shift"]] + 1, 'v',
@ -1073,7 +1054,7 @@ class MainWindow_precisely_align(QMainWindow):
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT)
self.stem_black1 = self.ax3.stem(arange(plot_element["back"]["shift"], self.stem_black1 = self.ax3.stem(arange(plot_element["back"]["shift"],
plot_element["back"]["shift"] + len(plot_element["back"]["JJIVs"])), plot_element["back"]["shift"] + len(plot_element["back"]["JJIVs"])),
plot_element["back"]["JJIVs"], markerfmt="ko", plot_element["back"]["JJIVs"], markerfmt="ko", linefmt=Constants.PLOT_COLOR_GREEN,
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV) label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
self.ax0.autoscale(False) self.ax0.autoscale(False)
@ -1090,7 +1071,6 @@ class MainWindow_precisely_align(QMainWindow):
return False, Constants.DRAWING_FAILURE return False, Constants.DRAWING_FAILURE
def redraw_correlation_align(self, plot_element=None): def redraw_correlation_align(self, plot_element=None):
if plot_element is not None and plot_element["mode"] == "select": if plot_element is not None and plot_element["mode"] == "select":
if self.selected_point0 is not None: if self.selected_point0 is not None:
self.selected_point0.remove() self.selected_point0.remove()
@ -1129,7 +1109,6 @@ class MainWindow_precisely_align(QMainWindow):
return False, Constants.DRAWING_FAILURE return False, Constants.DRAWING_FAILURE
def toggle_home(self): def toggle_home(self):
if self.ax0 is not None: if self.ax0 is not None:
self.ax0.autoscale(True) self.ax0.autoscale(True)
self.ax0.relim() self.ax0.relim()
@ -1164,7 +1143,6 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.text_output(self.ui, Constants.LABEL_CHECK_RECOVER_SCALE, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, Constants.LABEL_CHECK_RECOVER_SCALE, Constants.TIPS_TYPE_INFO)
def toggle_getRange(self, state): def toggle_getRange(self, state):
if state: if state:
self.deactivate_figToolbar_buttons() self.deactivate_figToolbar_buttons()
self.figToolbar.action_Get_Range.setChecked(True) self.figToolbar.action_Get_Range.setChecked(True)
@ -1186,7 +1164,6 @@ class MainWindow_precisely_align(QMainWindow):
self.figToolbar.cid_mouse_hold = None self.figToolbar.cid_mouse_hold = None
def deactivate_figToolbar_buttons(self): def deactivate_figToolbar_buttons(self):
for action in self.figToolbar._actions.values(): for action in self.figToolbar._actions.values():
if action.isChecked() == True: if action.isChecked() == True:
if action == self.figToolbar._actions['pan']: if action == self.figToolbar._actions['pan']:
@ -1195,7 +1172,6 @@ class MainWindow_precisely_align(QMainWindow):
self.figToolbar.zoom() self.figToolbar.zoom()
def on_click(self, event): def on_click(self, event):
if self.figToolbar.action_Get_Range.isChecked(): if self.figToolbar.action_Get_Range.isChecked():
if event.button == 1: if event.button == 1:
self.is_left_button_pressed = True self.is_left_button_pressed = True
@ -1222,7 +1198,6 @@ class MainWindow_precisely_align(QMainWindow):
self.canvas.draw() self.canvas.draw()
def on_release(self, event): def on_release(self, event):
if self.figToolbar.action_Get_Range.isChecked(): if self.figToolbar.action_Get_Range.isChecked():
if self.figToolbar.rect_start_x is not None: if self.figToolbar.rect_start_x is not None:
self.figToolbar.rect_end_x = event.xdata self.figToolbar.rect_end_x = event.xdata
@ -1321,7 +1296,6 @@ class MainWindow_precisely_align(QMainWindow):
self.canvas.draw() self.canvas.draw()
def on_hold(self, event): def on_hold(self, event):
if event.button == 1: if event.button == 1:
if self.figToolbar.rect_start_x is not None and event.xdata is not None: if self.figToolbar.rect_start_x is not None and event.xdata is not None:
self.figToolbar.rect_end_x = event.xdata self.figToolbar.rect_end_x = event.xdata
@ -1376,7 +1350,6 @@ class MainWindow_precisely_align(QMainWindow):
self.canvas.draw() self.canvas.draw()
def on_pick(self, event): def on_pick(self, event):
this_line = event.artist this_line = event.artist
if this_line.axes == self.ax0: if this_line.axes == self.ax0:
xdata = this_line.get_xdata() xdata = this_line.get_xdata()
@ -1412,20 +1385,6 @@ class MainWindow_precisely_align(QMainWindow):
class Data: class Data:
def __init__(self): def __init__(self):
self.file_path_input_orgBcg = Config["Path"]["Input_orgBcg"]
self.file_path_input_BCG = Config["Path"]["Input_BCG"]
self.file_path_input_Jpeak = Config["Path"]["Input_Jpeak"]
self.file_path_input_ECG = Config["Path"]["Input_ECG"]
self.file_path_input_Rpeak = Config["Path"]["Input_Rpeak"]
self.file_path_save_BCG_AlignInfo = Config["Path"]["Save_BCG_AlignInfo"]
self.file_path_save_ECG_AlignInfo = Config["Path"]["Save_ECG_AlignInfo"]
self.file_path_save_orgBcg = Config["Path"]["Save_orgBcg"]
self.file_path_save_BCG = Config["Path"]["Save_BCG"]
self.file_path_save_ECG = Config["Path"]["Save_ECG"]
self.file_path_save_Jpeak = Config["Path"]["Save_Jpeak"]
self.file_path_save_Rpeak = Config["Path"]["Save_Rpeak"]
self.raw_orgBcg = None self.raw_orgBcg = None
self.raw_BCG = None self.raw_BCG = None
self.Jpeak = None self.Jpeak = None
@ -1461,7 +1420,6 @@ class Data:
self.argmax_ECG = None self.argmax_ECG = None
def open_file(self): def open_file(self):
if ((not Path(Config["Path"]["Input_BCG"]).exists()) if ((not Path(Config["Path"]["Input_BCG"]).exists())
or (not Path(Config["Path"]["Input_Jpeak"]).exists()) or (not Path(Config["Path"]["Input_Jpeak"]).exists())
or (not Path(Config["Path"]["Input_ECG"]).exists()) or (not Path(Config["Path"]["Input_ECG"]).exists())
@ -1469,19 +1427,19 @@ class Data:
return False, Constants.INPUT_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Path_Not_Exist"] return False, Constants.INPUT_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Data_Path_Not_Exist"]
try: try:
self.raw_orgBcg = read_csv(self.file_path_input_orgBcg, self.raw_orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.raw_BCG = read_csv(Config["Path"]["Input_BCG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.raw_BCG = read_csv(self.file_path_input_BCG, self.Jpeak = read_csv(Config["Path"]["Input_Jpeak"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Jpeak = read_csv(self.file_path_input_Jpeak,
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.raw_ECG = read_csv(self.file_path_input_ECG, self.raw_ECG = read_csv(Config["Path"]["Input_ECG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Rpeak = read_csv(self.file_path_input_Rpeak, self.Rpeak = read_csv(Config["Path"]["Input_Rpeak"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.argmax_BCG = np_argmax(self.raw_BCG) self.argmax_BCG = np_argmax(self.raw_BCG)
@ -1492,7 +1450,6 @@ class Data:
return True, Constants.INPUT_FINISHED return True, Constants.INPUT_FINISHED
def data_process_for_calculate_correlation(self): def data_process_for_calculate_correlation(self):
result = {} result = {}
if self.Jpeak is None or self.Rpeak is None: if self.Jpeak is None or self.Rpeak is None:
@ -1511,7 +1468,6 @@ class Data:
return True, Constants.PRECISELY_ALIGN_PROCESS_FINISHED, result return True, Constants.PRECISELY_ALIGN_PROCESS_FINISHED, result
def calculate_correlation_front(self, mode, shift_front=None): def calculate_correlation_front(self, mode, shift_front=None):
result = {} result = {}
if ((Config["IV_Coordinate"]["BCG_front_1"] == Config["IV_Coordinate"]["BCG_front_2"]) if ((Config["IV_Coordinate"]["BCG_front_1"] == Config["IV_Coordinate"]["BCG_front_2"])
@ -1579,7 +1535,6 @@ class Data:
return True, Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_FRONT, result return True, Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_FRONT, result
def calculate_correlation_back(self, mode, shift_back=None): def calculate_correlation_back(self, mode, shift_back=None):
result = {} result = {}
if ((Config["IV_Coordinate"]["BCG_back_1"] == Config["IV_Coordinate"]["BCG_back_2"]) if ((Config["IV_Coordinate"]["BCG_back_1"] == Config["IV_Coordinate"]["BCG_back_2"])
@ -1647,7 +1602,6 @@ class Data:
return True, Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_BACK, result return True, Constants.PRECISELY_ALIGN_CALCULATE_FINISHED_BACK, result
def correlation_align(self, mode): def correlation_align(self, mode):
result = {} result = {}
try: try:
@ -1734,7 +1688,6 @@ class Data:
return True, Constants.PRECISELY_ALIGN_ALIGN_CORRELATION_FINISHED, result return True, Constants.PRECISELY_ALIGN_ALIGN_CORRELATION_FINISHED, result
def data_postprocess(self): def data_postprocess(self):
try: try:
if len(self.correlation_align_point_match_ECG) != 2 and len(self.correlation_align_point_match_BCG) != 2: if len(self.correlation_align_point_match_ECG) != 2 and len(self.correlation_align_point_match_BCG) != 2:
off = 0 off = 0
@ -1790,7 +1743,6 @@ class Data:
return True, f"{Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FINISHED}BCG前后段被切割的坐标值为[{frontcut_index_BCG}, {backcut_index_BCG}]ECG前后段被切割的坐标值为[{frontcut_index_ECG}, {backcut_index_ECG}]" return True, f"{Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FINISHED}BCG前后段被切割的坐标值为[{frontcut_index_BCG}, {backcut_index_BCG}]ECG前后段被切割的坐标值为[{frontcut_index_ECG}, {backcut_index_ECG}]"
def save_alignInfo(self): def save_alignInfo(self):
try: try:
save_data = { save_data = {
"front": { "front": {
@ -1823,69 +1775,63 @@ class Data:
} }
} }
save_data = [str(save_data)] save_data = [str(save_data)]
DataFrame(save_data).to_csv(self.file_path_save_BCG_AlignInfo, index=False, header=False) DataFrame(save_data).to_csv(Config["Path"]["Save_BCG_AlignInfo"], index=False, header=False)
DataFrame(save_data).to_csv(self.file_path_save_ECG_AlignInfo, index=False, header=False) DataFrame(save_data).to_csv(Config["Path"]["Save_ECG_AlignInfo"], index=False, header=False)
except Exception as e: except Exception:
print(e)
return False, Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"] return False, Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return True, Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FINISHED return True, Constants.PRECISELY_ALIGN_SAVING_ALIGNINFO_FINISHED
def save_res_orgBcg(self, chunk): def save_res_orgBcg(self, chunk):
if self.res_orgBcg is None: if self.res_orgBcg is None:
return False, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["res_orgBcg_Not_Exist"] return False, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["res_orgBcg_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save_orgBcg, mode='a', index=False, header=False) chunk.to_csv(Config["Path"]["Save_orgBcg"], mode='a', index=False, header=False)
except Exception: except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"] return False, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return True, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FINISHED return True, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FINISHED
def save_res_BCG(self, chunk): def save_res_BCG(self, chunk):
if self.res_BCG is None: if self.res_BCG is None:
return False, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["res_BCG_Not_Exist"] return False, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["res_BCG_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save_BCG, mode='a', index=False, header=False) chunk.to_csv(Config["Path"]["Save_BCG"], mode='a', index=False, header=False)
except Exception: except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"] return False, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return True, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FINISHED return True, Constants.PRECISELY_ALIGN_SAVING_RES_BCG_FINISHED
def save_cut_ECG(self, chunk): def save_cut_ECG(self, chunk):
if self.cut_ECG is None: if self.cut_ECG is None:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_ECG_Not_Exist"] return False, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_ECG_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save_ECG, mode='a', index=False, header=False) chunk.to_csv(Config["Path"]["Save_ECG"], mode='a', index=False, header=False)
except Exception: except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"] return False, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return True, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FINISHED return True, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG_FINISHED
def save_Jpeak(self, chunk): def save_Jpeak(self, chunk):
if self.cut_Jpeak is None: if self.cut_Jpeak is None:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_Jpeak_Not_Exist"] return False, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_Jpeak_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save_Jpeak, mode='a', index=False, header=False) chunk.to_csv(Config["Path"]["Save_Jpeak"], mode='a', index=False, header=False)
except Exception: except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"] return False, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
return True, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FINISHED return True, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK_FINISHED
def save_Rpeak(self, chunk): def save_Rpeak(self, chunk):
if self.cut_Rpeak is None: if self.cut_Rpeak is None:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_Rpeak_Not_Exist"] return False, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["cut_Rpeak_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save_Rpeak, mode='a', index=False, header=False) chunk.to_csv(Config["Path"]["Save_Rpeak"], mode='a', index=False, header=False)
except Exception: except Exception:
return False, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"] return False, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK_FAILURE + Constants.PRECISELY_ALIGN_FAILURE_REASON["Save_Exception"]
@ -1926,21 +1872,17 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
self.ax1_ECG_rectangle_back = None self.ax1_ECG_rectangle_back = None
def home(self, *args): def home(self, *args):
pass pass
def zoom(self, *args): def zoom(self, *args):
super().zoom(*args) super().zoom(*args)
self.deactivate_figToorbar_getRange_mode() self.deactivate_figToorbar_getRange_mode()
def pan(self, *args): def pan(self, *args):
super().pan(*args) super().pan(*args)
self.deactivate_figToorbar_getRange_mode() self.deactivate_figToorbar_getRange_mode()
def deactivate_figToorbar_getRange_mode(self): def deactivate_figToorbar_getRange_mode(self):
if self.action_Get_Range.isChecked(): if self.action_Get_Range.isChecked():
self.action_Get_Range.setChecked(False) self.action_Get_Range.setChecked(False)
if self.cid_mouse_press is not None: if self.cid_mouse_press is not None:

View File

@ -42,7 +42,6 @@ ButtonState = {
class SettingWindow(QMainWindow): class SettingWindow(QMainWindow):
def __init__(self, mode, root_path, sampID): def __init__(self, mode, root_path, sampID):
super(SettingWindow, self).__init__() super(SettingWindow, self).__init__()
self.ui = Ui_MainWindow_preprocess_input_setting() self.ui = Ui_MainWindow_preprocess_input_setting()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -61,7 +60,6 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.PREPROCESS_CONFIG_FILE_PATH).exists(): if not Path(ConfigParams.PREPROCESS_CONFIG_FILE_PATH).exists():
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f: with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PREPROCESS_CONFIG_NEW_CONTENT, f) dump(ConfigParams.PREPROCESS_CONFIG_NEW_CONTENT, f)
@ -109,7 +107,6 @@ class SettingWindow(QMainWindow):
self.ui.plainTextEdit_file_path_save.setPlainText(Config["Path"]["Save"]) self.ui.plainTextEdit_file_path_save.setPlainText(Config["Path"]["Save"])
def __write_config__(self): def __write_config__(self):
# 从界面写入配置 # 从界面写入配置
Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value() Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
Config["OutputConfig"]["Freq"] = self.ui.spinBox_output_freq.value() Config["OutputConfig"]["Freq"] = self.ui.spinBox_output_freq.value()
@ -126,11 +123,9 @@ class SettingWindow(QMainWindow):
self.close() self.close()
def __rollback_config__(self): def __rollback_config__(self):
self.__read_config__() self.__read_config__()
def __update_ui__(self): def __update_ui__(self):
if self.mode == "BCG": if self.mode == "BCG":
self.ui.plainTextEdit_file_path_input.setPlainText( self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
@ -168,7 +163,6 @@ class SettingWindow(QMainWindow):
class MainWindow_preprocess(QMainWindow): class MainWindow_preprocess(QMainWindow):
def __init__(self): def __init__(self):
super(MainWindow_preprocess, self).__init__() super(MainWindow_preprocess, self).__init__()
self.ui = Ui_MainWindow_preprocess() self.ui = Ui_MainWindow_preprocess()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -197,7 +191,6 @@ class MainWindow_preprocess(QMainWindow):
@overrides @overrides
def show(self, mode, root_path, sampID): def show(self, mode, root_path, sampID):
super().show() super().show()
self.mode = mode self.mode = mode
self.root_path = root_path self.root_path = root_path
@ -244,7 +237,6 @@ class MainWindow_preprocess(QMainWindow):
@overrides @overrides
def closeEvent(self, event): def closeEvent(self, event):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN)) PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
@ -264,12 +256,10 @@ class MainWindow_preprocess(QMainWindow):
@staticmethod @staticmethod
def __reset__(): def __reset__():
ButtonState["Current"].update(ButtonState["Default"].copy()) ButtonState["Current"].update(ButtonState["Default"].copy())
ButtonState["Current"]["pushButton_view"] = True ButtonState["Current"]["pushButton_view"] = True
def __plot__(self): def __plot__(self):
# 清空画框 # 清空画框
self.reset_axes() self.reset_axes()
@ -293,7 +283,6 @@ class MainWindow_preprocess(QMainWindow):
return status, info return status, info
def __update_config__(self): def __update_config__(self):
if self.mode == "BCG": if self.mode == "BCG":
Config["Filter"]["BCGBandPassOrder"] = self.ui.spinBox_bandPassOrder.value() Config["Filter"]["BCGBandPassOrder"] = self.ui.spinBox_bandPassOrder.value()
Config["Filter"]["BCGBandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value() Config["Filter"]["BCGBandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value()
@ -306,7 +295,6 @@ class MainWindow_preprocess(QMainWindow):
raise ValueError("模式不存在") raise ValueError("模式不存在")
def __slot_btn_input__(self): def __slot_btn_input__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 清空画框 # 清空画框
@ -331,7 +319,6 @@ class MainWindow_preprocess(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_view__(self): def __slot_btn_view__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 数据预处理 # 数据预处理
@ -360,7 +347,6 @@ class MainWindow_preprocess(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_save__(self): def __slot_btn_save__(self):
reply = QMessageBox.question(self, Constants.QUESTION_TITLE, reply = QMessageBox.question(self, Constants.QUESTION_TITLE,
Constants.QUESTION_CONTENT + Config["Path"]["Save"], Constants.QUESTION_CONTENT + Config["Path"]["Save"],
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes | QMessageBox.No,
@ -394,7 +380,6 @@ class MainWindow_preprocess(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def reset_axes(self): def reset_axes(self):
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
@ -403,20 +388,15 @@ class MainWindow_preprocess(QMainWindow):
class Data: class Data:
def __init__(self): def __init__(self):
self.file_path_input = Config["Path"]["Input"]
self.file_path_save = Config["Path"]["Save"]
self.raw_data = None self.raw_data = None
self.processed_data = None self.processed_data = None
def open_file(self): def open_file(self):
if not Path(Config["Path"]["Input"]).exists(): if not Path(Config["Path"]["Input"]).exists():
return False, Constants.INPUT_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Data_Path_Not_Exist"] return False, Constants.INPUT_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Data_Path_Not_Exist"]
try: try:
self.raw_data = read_csv(self.file_path_input, self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING, encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception: except Exception:
@ -425,7 +405,6 @@ class Data:
return True, Constants.INPUT_FINISHED return True, Constants.INPUT_FINISHED
def preprocess(self): def preprocess(self):
if self.raw_data is None: if self.raw_data is None:
return False, Constants.PREPROCESS_PROCESS_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Raw_Data_Not_Exist"] return False, Constants.PREPROCESS_PROCESS_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Raw_Data_Not_Exist"]
@ -454,12 +433,11 @@ class Data:
return True, Constants.PREPROCESS_PROCESS_FINISHED return True, Constants.PREPROCESS_PROCESS_FINISHED
def save(self, chunk): def save(self, chunk):
if self.processed_data is None: if self.processed_data is None:
return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Processed_Data_Not_Exist"] return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Processed_Data_Not_Exist"]
try: try:
chunk.to_csv(self.file_path_save, mode='a', index=False, header=False, float_format='%.4f') chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False, float_format='%.4f')
except Exception: except Exception:
return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Save_Exception"] return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Save_Exception"]

View File

@ -33,7 +33,7 @@ class ConfigParams:
# 预处理 # 预处理
PREPROCESS_CONFIG_FILE_PATH: str = "./config/Config_preprocess.yaml" PREPROCESS_CONFIG_FILE_PATH: str = "./config/Config_preprocess.yaml"
PREPROCESS_CONFIG_NEW_CONTENT = { PREPROCESS_CONFIG_NEW_CONTENT: dict = {
"InputConfig": { "InputConfig": {
"Freq": 1000 "Freq": 1000
}, },
@ -57,7 +57,7 @@ class ConfigParams:
# BCG的J峰算法定位 # BCG的J峰算法定位
DETECT_JPEAK_CONFIG_FILE_PATH: str = "./config/Config_detect_Jpeak.yaml" DETECT_JPEAK_CONFIG_FILE_PATH: str = "./config/Config_detect_Jpeak.yaml"
DETECT_JPEAK_CONFIG_NEW_CONTENT = { DETECT_JPEAK_CONFIG_NEW_CONTENT: dict = {
"InputConfig": { "InputConfig": {
"Freq": 1000 "Freq": 1000
}, },
@ -79,7 +79,7 @@ class ConfigParams:
# ECG的R峰算法定位 # ECG的R峰算法定位
DETECT_RPEAK_CONFIG_FILE_PATH: str = "./config/Config_detect_Rpeak.yaml" DETECT_RPEAK_CONFIG_FILE_PATH: str = "./config/Config_detect_Rpeak.yaml"
DETECT_RPEAK_CONFIG_NEW_CONTENT = { DETECT_RPEAK_CONFIG_NEW_CONTENT: dict = {
"InputConfig": { "InputConfig": {
"Freq": 1000 "Freq": 1000
}, },
@ -96,7 +96,7 @@ class ConfigParams:
# 人工纠正 # 人工纠正
LABEL_CHECK_CONFIG_FILE_PATH: str = "./config/Config_label_check.yaml" LABEL_CHECK_CONFIG_FILE_PATH: str = "./config/Config_label_check.yaml"
LABEL_CHECK_CONFIG_NEW_CONTENT = { LABEL_CHECK_CONFIG_NEW_CONTENT: dict = {
"InputConfig": { "InputConfig": {
"Freq": 1000 "Freq": 1000
}, },
@ -130,7 +130,7 @@ class ConfigParams:
# 数据精同步 # 数据精同步
PRECISELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_precisely_align.yaml" PRECISELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_precisely_align.yaml"
PRECISELY_ALIGN_CONFIG_NEW_CONTENT = { PRECISELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
"InputConfig": { "InputConfig": {
"ECGFreq": 1000 "ECGFreq": 1000
} }
@ -152,10 +152,46 @@ class ConfigParams:
PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE: int = 100 PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE: int = 100
# 冗余数据切割和标签映射 # 冗余数据切割和标签映射
CUT_PSG_CONFIG_FILE_PATH: str = "./config/Config_cut_PSG.yaml"
CUT_PSG_CONFIG_NEW_CONTENT: dict = {
"ECGFreq": 1000,
"ChannelInput": {
"Effort Tho": "Effort Tho_Raw_",
"Effort Abd": "Effort Abd_Raw_",
"Flow Patient": "Flow Patient_Raw_",
"Snore": "Snore_Raw_",
"SpO2": "SpO2_Raw_",
"5_class": "5_class_Raw_"
},
"LabelInput": {
"SA Label": "SA Label_Raw"
},
"StartTime": "StartTime_Raw",
"ChannelSave": {
"Effort Tho": "Effort Tho_Sync_",
"Effort Abd": "Effort Abd_Sync_",
"Flow Patient": "Flow Patient_Sync_",
"Snore": "Snore_Sync_",
"SpO2": "SpO2_Sync_",
"5_class": "5_class_Sync_"
},
"LabelSave": {
"SA Label": "SA Label_Sync"
},
"EndWith": {
"Effort Tho": ENDSWITH_TXT,
"Effort Abd": ENDSWITH_TXT,
"Flow Patient": ENDSWITH_TXT,
"Snore": ENDSWITH_TXT,
"SpO2": ENDSWITH_TXT,
"5_class": ENDSWITH_TXT,
"SA Label": ENDSWITH_CSV,
"StartTime": ENDSWITH_TXT
},
}
CUT_PSG_SAVE_ECG_ALIGNINFO_FILENAME: str = "Align_info"
CUT_PSG_SALABEL_EVENT: list = ["Hypopnea", "Central apnea", "Obstructive apnea", "Mixed apnea"]
CUT_PSG_CHANNEL_LIST: list = ["Effort Abd_Raw_", "Effort Tho_Raw_", "Flow Patient_Raw_", "Snore_Raw_", "SpO2_Raw_"]
CUT_PST_LABEL_LIST: list = ["5_class_Raw_", "SA Label_Raw"]
CUT_PST_STARTTIME: list = ["StartTime_Raw"]
# 体动标注 # 体动标注

View File

@ -269,6 +269,32 @@ class Constants:
PRECISELY_ALIGN_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无有效点" PRECISELY_ALIGN_NO_POINT_IN_THE_INTERVAL: 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"设置范围({ConfigParams.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY})"
# 冗余数据切割和标签映射
CUT_PSG_GETTING_FILE_AND_FREQ: str = "正在获取文件及其采样率"
CUT_PSG_GET_FILE_AND_FREQ_FINISHED: str = "获取文件及其采样率完成"
CUT_PSG_GET_FILE_AND_FREQ_FAILURE: str = "获取文件及其采样率失败"
CUT_PSG_CUTTING_DATA: str = "正在切割数据"
CUT_PSG_CUT_DATA_FINISHED: str = "切割数据完成"
CUT_PSG_CUT_DATA_FAILURE: str = "切割数据失败"
CUT_PSG_ALIGNING_LABEL: str = "正在映射标签"
CUT_PSG_ALIGN_LABEL_FINISHED: str = "映射标签完成"
CUT_PSG_ALIGN_LABEL_FAILURE: str = "映射标签失败"
CUT_PSG_FAILURE_REASON: str = {
"Filename_Format_not_Correct": "(文件名格式不正确)",
"File_not_Exist": "(需要处理的文件不存在)",
"Get_File_and_Freq_Excepetion": "(检查文件是否存在并获取其数据采样率异常)",
"Read_Data_Exception": "(读取数据异常)",
"Cut_Data_Length_not_Correct": "(切割数据时长度不正确)",
"Cut_Data_Exception": "(切割数据异常)",
"Align_Label_SALabel_Format_not_Correct": "映射标签时SA Label中的文件格式不正确",
"Align_Label_Exception": "(映射标签异常)",
"Save_Data_not_Exist": "(需要保存的数据不存在)",
"Save_Exception": "(保存异常)"
}
# 体动标注 # 体动标注
# TODO弃用 # TODO弃用

View File

@ -130,7 +130,6 @@ class PublicFunc:
@staticmethod @staticmethod
def add_progressbar(mainWindow): def add_progressbar(mainWindow):
mainWindow.progressbar = QProgressBar() mainWindow.progressbar = QProgressBar()
mainWindow.progressbar.setRange(0, 100) mainWindow.progressbar.setRange(0, 100)
mainWindow.progressbar.setValue(0) mainWindow.progressbar.setValue(0)
@ -139,17 +138,14 @@ class PublicFunc:
@staticmethod @staticmethod
def statusbar_show_msg(mainWindow, msg): def statusbar_show_msg(mainWindow, msg):
mainWindow.ui.statusbar.showMessage(msg) mainWindow.ui.statusbar.showMessage(msg)
@staticmethod @staticmethod
def statusbar_clear_msg(mainWindow): def statusbar_clear_msg(mainWindow):
mainWindow.ui.statusbar.clearMessage() mainWindow.ui.statusbar.clearMessage()
@staticmethod @staticmethod
def finish_operation(mainWindow, buttonState): def finish_operation(mainWindow, buttonState):
PublicFunc.statusbar_show_msg(mainWindow, PublicFunc.format_status_msg(Constants.OPERATION_FINISHED)) PublicFunc.statusbar_show_msg(mainWindow, PublicFunc.format_status_msg(Constants.OPERATION_FINISHED))
mainWindow.progressbar.setValue(100) mainWindow.progressbar.setValue(100)
QApplication.processEvents() QApplication.processEvents()
@ -158,7 +154,6 @@ class PublicFunc:
@staticmethod @staticmethod
def progressbar_update(mainWindow, current: int, total: int, msg: str, progressbarState: int): def progressbar_update(mainWindow, current: int, total: int, msg: str, progressbarState: int):
if current > total: if current > total:
raise ValueError("当前进度值大于总进度值") raise ValueError("当前进度值大于总进度值")
if progressbarState < 0 or progressbarState > 100: if progressbarState < 0 or progressbarState > 100:

View File

@ -18,8 +18,8 @@ from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
QTransform) QTransform)
from PySide6.QtWidgets import (QApplication, QGridLayout, QGroupBox, QHBoxLayout, from PySide6.QtWidgets import (QApplication, QGridLayout, QGroupBox, QHBoxLayout,
QLabel, QMainWindow, QPlainTextEdit, QProgressBar, QLabel, QMainWindow, QPlainTextEdit, QProgressBar,
QPushButton, QSizePolicy, QSpacerItem, QStatusBar, QPushButton, QSizePolicy, QSpacerItem, QSpinBox,
QTextBrowser, QVBoxLayout, QWidget) QStatusBar, QTextBrowser, QVBoxLayout, QWidget)
class Ui_MainWindow_cut_PSG(object): class Ui_MainWindow_cut_PSG(object):
def setupUi(self, MainWindow_cut_PSG): def setupUi(self, MainWindow_cut_PSG):
@ -82,6 +82,7 @@ class Ui_MainWindow_cut_PSG(object):
self.plainTextEdit_channel = QPlainTextEdit(self.groupBox_2) self.plainTextEdit_channel = QPlainTextEdit(self.groupBox_2)
self.plainTextEdit_channel.setObjectName(u"plainTextEdit_channel") self.plainTextEdit_channel.setObjectName(u"plainTextEdit_channel")
self.plainTextEdit_channel.setEnabled(False)
self.horizontalLayout.addWidget(self.plainTextEdit_channel) self.horizontalLayout.addWidget(self.plainTextEdit_channel)
@ -100,6 +101,7 @@ class Ui_MainWindow_cut_PSG(object):
self.plainTextEdit_label = QPlainTextEdit(self.groupBox_2) self.plainTextEdit_label = QPlainTextEdit(self.groupBox_2)
self.plainTextEdit_label.setObjectName(u"plainTextEdit_label") self.plainTextEdit_label.setObjectName(u"plainTextEdit_label")
self.plainTextEdit_label.setEnabled(False)
self.horizontalLayout_6.addWidget(self.plainTextEdit_label) self.horizontalLayout_6.addWidget(self.plainTextEdit_label)
@ -108,6 +110,27 @@ class Ui_MainWindow_cut_PSG(object):
self.verticalLayout_5.addLayout(self.horizontalLayout_6) self.verticalLayout_5.addLayout(self.horizontalLayout_6)
self.horizontalLayout_7 = QHBoxLayout()
self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
self.label_7 = QLabel(self.groupBox_2)
self.label_7.setObjectName(u"label_7")
self.label_7.setFont(font)
self.horizontalLayout_7.addWidget(self.label_7)
self.spinBox_ECGFreq = QSpinBox(self.groupBox_2)
self.spinBox_ECGFreq.setObjectName(u"spinBox_ECGFreq")
self.spinBox_ECGFreq.setFont(font)
self.spinBox_ECGFreq.setMinimum(1)
self.spinBox_ECGFreq.setMaximum(1000000)
self.horizontalLayout_7.addWidget(self.spinBox_ECGFreq)
self.horizontalLayout_7.setStretch(0, 1)
self.horizontalLayout_7.setStretch(1, 1)
self.verticalLayout_5.addLayout(self.horizontalLayout_7)
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_5.addItem(self.verticalSpacer) self.verticalLayout_5.addItem(self.verticalSpacer)
@ -124,23 +147,24 @@ class Ui_MainWindow_cut_PSG(object):
self.verticalLayout_5.addLayout(self.horizontalLayout_2) self.verticalLayout_5.addLayout(self.horizontalLayout_2)
self.progressBar = QProgressBar(self.groupBox_2) self.progressbar = QProgressBar(self.groupBox_2)
self.progressBar.setObjectName(u"progressBar") self.progressbar.setObjectName(u"progressbar")
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred) sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
sizePolicy1.setHorizontalStretch(0) sizePolicy1.setHorizontalStretch(0)
sizePolicy1.setVerticalStretch(0) sizePolicy1.setVerticalStretch(0)
sizePolicy1.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth()) sizePolicy1.setHeightForWidth(self.progressbar.sizePolicy().hasHeightForWidth())
self.progressBar.setSizePolicy(sizePolicy1) self.progressbar.setSizePolicy(sizePolicy1)
self.progressBar.setStyleSheet(u"") self.progressbar.setStyleSheet(u"")
self.progressBar.setValue(0) self.progressbar.setValue(0)
self.verticalLayout_5.addWidget(self.progressBar) self.verticalLayout_5.addWidget(self.progressbar)
self.verticalLayout_5.setStretch(0, 2) self.verticalLayout_5.setStretch(0, 2)
self.verticalLayout_5.setStretch(1, 2) self.verticalLayout_5.setStretch(1, 2)
self.verticalLayout_5.setStretch(2, 2) self.verticalLayout_5.setStretch(2, 1)
self.verticalLayout_5.setStretch(3, 1) self.verticalLayout_5.setStretch(3, 2)
self.verticalLayout_5.setStretch(4, 1) self.verticalLayout_5.setStretch(4, 1)
self.verticalLayout_5.setStretch(5, 1)
self.gridLayout_2.addWidget(self.groupBox_2, 0, 0, 1, 2) self.gridLayout_2.addWidget(self.groupBox_2, 0, 0, 1, 2)
@ -182,6 +206,7 @@ class Ui_MainWindow_cut_PSG(object):
self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_cut_PSG", u"\u786e\u5b9a\u6570\u636e", None)) self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_cut_PSG", u"\u786e\u5b9a\u6570\u636e", None))
self.label_2.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u9700\u8981\u5207\u5272\u7684\u901a\u9053\u540d\uff1a", None)) self.label_2.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u9700\u8981\u5207\u5272\u7684\u901a\u9053\u540d\uff1a", None))
self.label_6.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u9700\u8981\u6620\u5c04\u7684\u6807\u7b7e\uff1a", None)) self.label_6.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u9700\u8981\u6620\u5c04\u7684\u6807\u7b7e\uff1a", None))
self.label_7.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u6570\u636e\u7cbe\u540c\u6b65\u65f6ECG\u7684\u91c7\u6837\u7387\uff1a", None))
self.label_show.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u70b9\u51fb\u6267\u884c\u4ee5\u5f00\u59cb...", None)) self.label_show.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u70b9\u51fb\u6267\u884c\u4ee5\u5f00\u59cb...", None))
self.pushButton_execute.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u6267\u884c", None)) self.pushButton_execute.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u6267\u884c", None))
# retranslateUi # retranslateUi

View File

@ -57,7 +57,7 @@
<property name="title"> <property name="title">
<string>确定数据</string> <string>确定数据</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="2,2,2,1,1"> <layout class="QVBoxLayout" name="verticalLayout_5" stretch="2,2,1,2,1,1">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1"> <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
<item> <item>
@ -76,7 +76,11 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPlainTextEdit" name="plainTextEdit_channel"/> <widget class="QPlainTextEdit" name="plainTextEdit_channel">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -95,7 +99,42 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPlainTextEdit" name="plainTextEdit_label"/> <widget class="QPlainTextEdit" name="plainTextEdit_label">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7" stretch="1,1">
<item>
<widget class="QLabel" name="label_7">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>数据精同步时ECG的采样率</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_ECGFreq">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -132,7 +171,7 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QProgressBar" name="progressBar"> <widget class="QProgressBar" name="progressbar">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>

View File

@ -151,13 +151,28 @@ class Ui_Signal_Label(object):
self.verticalLayout.addLayout(self.horizontalLayout_6) self.verticalLayout.addLayout(self.horizontalLayout_6)
self.horizontalLayout_4 = QHBoxLayout()
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
self.pushButton_precisely_align = QPushButton(self.centralwidget) self.pushButton_precisely_align = QPushButton(self.centralwidget)
self.pushButton_precisely_align.setObjectName(u"pushButton_precisely_align") self.pushButton_precisely_align.setObjectName(u"pushButton_precisely_align")
sizePolicy.setHeightForWidth(self.pushButton_precisely_align.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.pushButton_precisely_align.sizePolicy().hasHeightForWidth())
self.pushButton_precisely_align.setSizePolicy(sizePolicy) self.pushButton_precisely_align.setSizePolicy(sizePolicy)
self.pushButton_precisely_align.setFont(font) self.pushButton_precisely_align.setFont(font)
self.verticalLayout.addWidget(self.pushButton_precisely_align) self.horizontalLayout_4.addWidget(self.pushButton_precisely_align)
self.pushButton_cut_PSG = QPushButton(self.centralwidget)
self.pushButton_cut_PSG.setObjectName(u"pushButton_cut_PSG")
sizePolicy.setHeightForWidth(self.pushButton_cut_PSG.sizePolicy().hasHeightForWidth())
self.pushButton_cut_PSG.setSizePolicy(sizePolicy)
self.pushButton_cut_PSG.setFont(font)
self.horizontalLayout_4.addWidget(self.pushButton_cut_PSG)
self.horizontalLayout_4.setStretch(0, 3)
self.horizontalLayout_4.setStretch(1, 1)
self.verticalLayout.addLayout(self.horizontalLayout_4)
self.pushButton_artifact_label = QPushButton(self.centralwidget) self.pushButton_artifact_label = QPushButton(self.centralwidget)
self.pushButton_artifact_label.setObjectName(u"pushButton_artifact_label") self.pushButton_artifact_label.setObjectName(u"pushButton_artifact_label")
@ -226,6 +241,7 @@ class Ui_Signal_Label(object):
self.pushButton_label_check_BCG.setText(QCoreApplication.translate("Signal_Label", u"BCG\u7684J\u5cf0\u4eba\u5de5\u7ea0\u6b63", None)) self.pushButton_label_check_BCG.setText(QCoreApplication.translate("Signal_Label", u"BCG\u7684J\u5cf0\u4eba\u5de5\u7ea0\u6b63", None))
self.pushButton_label_check_ECG.setText(QCoreApplication.translate("Signal_Label", u"ECG\u7684R\u5cf0\u4eba\u5de5\u7ea0\u6b63", None)) self.pushButton_label_check_ECG.setText(QCoreApplication.translate("Signal_Label", u"ECG\u7684R\u5cf0\u4eba\u5de5\u7ea0\u6b63", None))
self.pushButton_precisely_align.setText(QCoreApplication.translate("Signal_Label", u"\u6570\u636e\u7cbe\u540c\u6b65", None)) self.pushButton_precisely_align.setText(QCoreApplication.translate("Signal_Label", u"\u6570\u636e\u7cbe\u540c\u6b65", None))
self.pushButton_cut_PSG.setText(QCoreApplication.translate("Signal_Label", u"\u5197\u4f59\u6570\u636e\u5207\u5272\u548c\u6807\u7b7e\u6620\u5c04", None))
self.pushButton_artifact_label.setText(QCoreApplication.translate("Signal_Label", u"\u4f53\u52a8\u6807\u6ce8", None)) self.pushButton_artifact_label.setText(QCoreApplication.translate("Signal_Label", u"\u4f53\u52a8\u6807\u6ce8", None))
self.pushButton_bcg_quality_label.setText(QCoreApplication.translate("Signal_Label", u"BCG\u7684\u8d28\u91cf\u6807\u6ce8", None)) self.pushButton_bcg_quality_label.setText(QCoreApplication.translate("Signal_Label", u"BCG\u7684\u8d28\u91cf\u6807\u6ce8", None))
self.pushButton_resp_quality_label.setText(QCoreApplication.translate("Signal_Label", u"\u547c\u5438\u53ef\u7528\u6027\u53ca\u95f4\u671f\u6807\u6ce8", None)) self.pushButton_resp_quality_label.setText(QCoreApplication.translate("Signal_Label", u"\u547c\u5438\u53ef\u7528\u6027\u53ca\u95f4\u671f\u6807\u6ce8", None))

View File

@ -223,22 +223,44 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_precisely_align"> <layout class="QHBoxLayout" name="horizontalLayout_4" stretch="3,1">
<property name="sizePolicy"> <item>
<sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <widget class="QPushButton" name="pushButton_precisely_align">
<horstretch>0</horstretch> <property name="sizePolicy">
<verstretch>0</verstretch> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
</sizepolicy> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
<property name="font"> </sizepolicy>
<font> </property>
<pointsize>14</pointsize> <property name="font">
</font> <font>
</property> <pointsize>14</pointsize>
<property name="text"> </font>
<string>数据精同步</string> </property>
</property> <property name="text">
</widget> <string>数据精同步</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_cut_PSG">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>冗余数据切割和标签映射</string>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_artifact_label"> <widget class="QPushButton" name="pushButton_artifact_label">

View File

@ -16,7 +16,7 @@
|-SA Label_corrected.csv |-SA Label_corrected.csv
|-SA Label_add.csv` |-SA Label_add.csv`
.../OrgBCG_Aligned/<sampID> .../OrgBCG_Aligned/<sampID>
|-Align_info.txt |-Align_info.yaml
|-BCG_Sync_采样率.txt |-BCG_Sync_采样率.txt
|-orgBcg_Sync_采样率.txt |-orgBcg_Sync_采样率.txt
|-Jpeak_Sync.txt |-Jpeak_Sync.txt
@ -28,7 +28,7 @@
.../OrgBCG_Origin/<sampID> .../OrgBCG_Origin/<sampID>
|-... |-...
.../PSG_Aligned/<sampID> .../PSG_Aligned/<sampID>
|-Align_info.txt |-Align_info.yaml
|-ECG_Sync_采样率.txt |-ECG_Sync_采样率.txt
|-Rpeak_Sync.txt |-Rpeak_Sync.txt
|-5_class_Sync_1.txt |-5_class_Sync_1.txt
@ -168,13 +168,13 @@
输出: 输出:
PSG的对齐信息`./PSG_Aligned/<sampID>/Align_info.txt` PSG的对齐信息`./PSG_Aligned/<sampID>/Align_info.yaml`
同步后的ECG信号`./PSG_Aligned/<sampID>/ECG_Sync_采样率.txt` 同步后的ECG信号`./PSG_Aligned/<sampID>/ECG_Sync_采样率.txt`
同步后的R峰坐标`./PSG_Aligned/<sampID>/Rpeak_Sync.txt` 同步后的R峰坐标`./PSG_Aligned/<sampID>/Rpeak_Sync.txt`
BCG的对齐信息`./OrgBCG_Aligned/<sampID>/Align_info.txt` BCG的对齐信息`./OrgBCG_Aligned/<sampID>/Align_info.yaml`
同步后的BCG信号`./OrgBCG_Aligned/<sampID>/BCG_Sync_采样率.txt` 同步后的BCG信号`./OrgBCG_Aligned/<sampID>/BCG_Sync_采样率.txt`
@ -188,9 +188,9 @@ BCG的对齐信息`./OrgBCG_Aligned/<sampID>/Align_info.txt`
输入: 输入:
PSG的对齐信息`./PSG_Aligned/<sampID>/Align_info.txt` PSG的对齐信息`./PSG_Aligned/<sampID>/Align_info.yaml`
BCG的对齐信息`./OrgBCG_Aligned/<sampID>/Align_info.txt` BCG的对齐信息`./OrgBCG_Aligned/<sampID>/Align_info.yaml`
原始的其他PSG通道信号`./PSG_Text/<sampID>/通道名_Raw_采样率.txt`通道名包括Effort Abd, Effort Tho, Flow Patient, Snore, SpO2 原始的其他PSG通道信号`./PSG_Text/<sampID>/通道名_Raw_采样率.txt`通道名包括Effort Abd, Effort Tho, Flow Patient, Snore, SpO2