优化<冗余数据切割和标签映射>的代码

删去了<冗余数据切割和标签映射>的自动最大化
This commit is contained in:
Yorusora
2025-05-20 21:02:03 +08:00
parent 900912090a
commit db07be0ca7
6 changed files with 1275 additions and 114 deletions

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,7 @@ class MainWindow_cut_PSG(QMainWindow):
"Path": {
"InputFolder": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT / Path(str(self.sampID))),
"SaveFolder": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Path(str(self.sampID))),
"InputAlignInfo": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL / Path(str(self.sampID)) / (ConfigParams.CUT_PSG_SAVE_ECG_ALIGNINFO_FILENAME + ConfigParams.ENDSWITH_TXT))
"InputAlignInfo": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL / Path(str(self.sampID)))
}
})
@ -108,7 +108,7 @@ class MainWindow_cut_PSG(QMainWindow):
def __slot_btn_execute__(self):
PublicFunc.__disableAllButton__(self, ButtonState)
self.data = Data()
self.data = Data(self.root_path, self.sampID)
Config["ECGFreq"] = self.ui.spinBox_ECGFreq.value()
# 检查文件是否存在并获取其数据采样率
@ -185,7 +185,7 @@ class MainWindow_cut_PSG(QMainWindow):
class Data:
def __init__(self):
def __init__(self, root_path, sampID):
self.alignInfo = None
self.raw = {key: array([]) for key in Config["ChannelInput"]}
@ -194,6 +194,9 @@ class Data:
self.SALabel = None
self.startTime = None
self.root_path = root_path
self.sampID = sampID
def get_file_and_freq(self):
try:
for file_path in Path(Config["Path"]["InputFolder"]).glob('*'):
@ -206,22 +209,41 @@ class Data:
freq = int(freq_str)
self.freq[key] = freq
except ValueError:
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Filename_Format_not_Correct"])
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
Constants.FAILURE_REASON["Filename_Format_not_Correct"])
for value in self.freq.values():
if value == 0:
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Filename_Format_not_Correct"])
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
Constants.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 Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"])
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
Constants.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 Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"])
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
Constants.FAILURE_REASON["File_not_Exist"])
if not Path(Config["Path"]["InputAlignInfo"]).exists():
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_FAILURE_REASON["File_not_Exist"])
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
Constants.FAILURE_REASON["File_not_Exist"])
except Exception as e:
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE + Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE["Get_File_and_Freq_Excepetion"] + "\n" + format_exc())
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
Constants.FAILURE_REASON["Get_File_and_Freq_Excepetion"] + "\n" + format_exc())
return Result().success(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FINISHED)
def open_file(self):
path = str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT / Path(str(self.sampID)))
for value in Config["ChannelInput"].values():
result = PublicFunc.examine_file(path, value)
if not result.status:
return result
if Path(Config["Path"]["InputAlignInfo"]).is_file():
Config["Path"]["InputAlignInfo"] = str(Path(Config["Path"]["InputAlignInfo"]).parent)
Config["Path"]["InputAlignInfo"] = str(
Path(Config["Path"]["InputAlignInfo"]) / Path(
ConfigParams.PRECISELY_ALIGN_INFO + ConfigParams.ENDSWITH_TXT))
try:
for key in Config["ChannelInput"].keys():
self.raw[key] = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["ChannelInput"][key] + str(self.freq[key]) + Config["EndWith"][key])),
@ -237,7 +259,8 @@ class Data:
header=None).to_numpy().reshape(-1)
self.alignInfo = literal_eval(self.alignInfo[0])
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Read_Data_Exception"] + "\n" + format_exc())
return Result().failure(info=Constants.INPUT_FAILURE +
Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.INPUT_FINISHED)
@ -255,9 +278,11 @@ class Data:
# 切割信号
self.raw[key] = self.raw[key][start_index_cut:end_index_cut]
except Exception:
return Result().failure(info=Constants.CUT_PSG_CUT_DATA_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Cut_Data_Length_not_Correct"])
return Result().failure(info=Constants.CUT_PSG_CUT_DATA_FAILURE +
Constants.FAILURE_REASON["Cut_Data_Length_not_Correct"])
except Exception as e:
return Result().failure(info=Constants.CUT_PSG_CUT_DATA_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Cut_Data_Exception"] + "\n" + format_exc())
return Result().failure(info=Constants.CUT_PSG_CUT_DATA_FAILURE +
Constants.FAILURE_REASON["Cut_Data_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.CUT_PSG_CUT_DATA_FINISHED)
@ -269,7 +294,8 @@ class Data:
self.SALabel["Duration"] = self.SALabel["Duration"].astype(str)
self.SALabel["Duration"] = self.SALabel["Duration"].str.replace(r' \(.*?\)', '', regex=True)
except Exception:
return Result().failure(info=Constants.CUT_PSG_ALIGN_LABEL_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Align_Label_SALabel_Format_not_Correct"])
return Result().failure(info=Constants.CUT_PSG_ALIGN_LABEL_FAILURE +
Constants.FAILURE_REASON["Align_Label_SALabel_Format_not_Correct"])
try:
# 获取记录开始时间
@ -290,14 +316,16 @@ class Data:
self.SALabel = self.SALabel[self.SALabel["Start"] < ECG_length]
self.SALabel.loc[self.SALabel["End"] >= ECG_length, "End"] = ECG_length - 1
except Exception as e:
return Result().failure(info=Constants.CUT_PSG_ALIGN_LABEL_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Align_Label_Exception"] + "\n" + format_exc())
return Result().failure(info=Constants.CUT_PSG_ALIGN_LABEL_FAILURE +
Constants.FAILURE_REASON["Align_Label_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.CUT_PSG_ALIGN_LABEL_FINISHED)
def save(self):
for raw in self.raw.values():
if len(raw) == 0:
return Result().failure(info=Constants.SAVING_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Save_Data_not_Exist"])
return Result().failure(info=Constants.SAVING_FAILURE +
Constants.FAILURE_REASON["Data_not_Exist"])
try:
for key, raw in self.raw.items():
@ -307,7 +335,8 @@ class Data:
index=False,
encoding="gbk")
except Exception as e:
return Result().failure(info=Constants.SAVING_FAILURE + Constants.CUT_PSG_FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
return Result().failure(info=Constants.SAVING_FAILURE +
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.SAVING_FINISHED)

View File

@ -415,7 +415,7 @@ class Data:
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE +
Constants.FAILURE_REASON["Read_Data_Exception"] + "\n" + format_exc())
Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.INPUT_FINISHED)

View File

@ -209,8 +209,6 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
if not self.check_sampID():
return
self.cut_PSG.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率
self.cut_PSG.showMaximized()
def __slot_btn_artifact_label__(self):
self.artifact_label = MainWindow_artifact_label()

View File

@ -35,6 +35,9 @@ class ConfigParams:
ABD_RAW: str = "Effort Abd_Raw_"
FLOWT_RAW: str = "Flow T_Raw_"
FLOWP_RAW: str = "Flow P_Raw_"
SNORE_RAW: str = "Snore_Raw_"
SPO2_RAW: str = "SpO2_Raw_"
FIVE_CLASS_RAW: str = "5_class_Raw_"
BCG_FILTER: str = "BCG_Filter_"
ECG_FILTER: str = "ECG_Filter_"
JPEAK_REVISE: str = "Jpeak_revise_"
@ -49,6 +52,9 @@ class ConfigParams:
ABD_SYNC: str = "Effort Abd_Sync_"
FLOWT_SYNC: str = "Flow T_Sync_"
FLOWP_SYNC: str = "Flow P_Sync_"
SNORE_SYNC: str = "Snore_Sync_"
SPO2_SYNC: str = "SpO2_Sync_"
FIVE_CLASS_SYNC: str = "5_class_Sync_"
BCG_SYNC: str = "BCG_Sync_"
ECG_SYNC: str = "ECG_Sync_"
JPEAK_SYNC: str = "Jpeak_Sync_"
@ -100,10 +106,6 @@ class ConfigParams:
"ECGBandPassHigh": 25
}
}
PREPROCESS_INPUT_BCG_FILENAME: str = "OrgBCG_Raw_"
PREPROCESS_INPUT_ECG_FILENAME: str = "ECG II_Raw_"
PREPROCESS_SAVE_BCG_FILENAME: str = "BCG_Filter_"
PREPROCESS_SAVE_ECG_FILENAME: str = "ECG_Filter_"
PREPROCESS_SAVE_CHUNK_SIZE: int = 1000000
# BCG的J峰算法定位
@ -124,8 +126,6 @@ class ConfigParams:
"UseCPU": False,
"DetectMethod": ""
}
DETECT_JPEAK_INPUT_BCG_FILENAME: str = "BCG_Filter_"
DETECT_JPEAK_SAVE_FILENAME: str = "JPeak_revise"
DETECT_JPEAK_SAVE_CHUNK_SIZE: int = 100
# ECG的R峰算法定位
@ -141,8 +141,6 @@ class ConfigParams:
"PeaksValue": 200,
"DetectMethod": ""
}
DETECT_RPEAK_INPUT_ECG_FILENAME: str = "ECG_Filter_"
DETECT_RPEAK_SAVE_FILENAME: str = "Rpeak_final"
DETECT_RPEAK_SAVE_CHUNK_SIZE: int = 100
# 人工纠正
@ -169,13 +167,6 @@ class ConfigParams:
"MoveSpeed": 1000
}
}
LABEL_CHECK_INPUT_BCG_FILENAME: str = "BCG_Filter_"
LABEL_CHECK_INPUT_JPEAK_FILENAME: str = "JPeak_revise"
LABEL_CHECK_SAVE_JPEAK_FILENAME: str = "JPeak_revise_corrected"
LABEL_CHECK_INPUT_ECG_FILENAME: str = "ECG_Filter_"
LABEL_CHECK_INPUT_RPEAK_FILENAME: str = "Rpeak_final"
LABEL_CHECK_SAVE_RPEAK_FILENAME: str = "Rpeak_final_corrected"
LABEL_CHECK_APPROXIMATELY_ALIGNINFO_FILENAME: str = "Approximately_Align_Info"
LABEL_CHECK_SAVE_CHUNK_SIZE: int = 100
LABEL_CHECK_LABEL_TRANSPARENCY: float = 0.2
LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
@ -190,18 +181,6 @@ class ConfigParams:
"UseFreq": 1000
}
}
PRECISELY_ALIGN_INPUT_ORGBCG_FILENAME: str = "OrgBCG_Raw_"
PRECISELY_ALIGN_INPUT_BCG_FILENAME: str = "BCG_Filter_"
PRECISELY_ALIGN_INPUT_JPEAK_FILENAME: str = "JPeak_revise_corrected"
PRECISELY_ALIGN_SAVE_ALIGNINFO_FILENAME: str = "Align_info"
PRECISELY_ALIGN_INPUT_ECG_FILENAME: str = "ECG_Filter_"
PRECISELY_ALIGN_INPUT_RPEAK_FILENAME: str = "Rpeak_final_corrected"
PRECISELY_ALIGN_SAVE_ORGBCG_FILENAME: str = "OrgBCG_Sync_"
PRECISELY_ALIGN_SAVE_BCG_FILENAME: str = "BCG_Sync_"
PRECISELY_ALIGN_SAVE_ECG_FILENAME: str = "ECG_Sync_"
PRECISELY_ALIGN_SAVE_JPEAK_FILENAME: str = "JPeak_Sync"
PRECISELY_ALIGN_SAVE_RPEAK_FILENAME: str = "Rpeak_Sync"
PRECISELY_ALIGN_APPROXIMATELY_ALIGNINFO_FILENAME: str = "Approximately_Align_Info"
PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY: str = "Z"
PRECISELY_ALIGN_SAVE_CHUNK_SIZE: int = 1000000
PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE: int = 100
@ -212,26 +191,26 @@ class ConfigParams:
CUT_PSG_CONFIG_NEW_CONTENT: dict = {
"ECGFreq": 1000,
"ChannelInput": {
"Effort Tho": "Effort Tho_Raw_",
"Effort Abd": "Effort Abd_Raw_",
"Flow T": "Flow T_Raw_",
"Flow P": "Flow P_Raw_",
"Snore": "Snore_Raw_",
"SpO2": "SpO2_Raw_",
"5_class": "5_class_Raw_"
"Effort Tho": THO_RAW,
"Effort Abd": ABD_RAW,
"Flow T": FLOWT_RAW,
"Flow P": FLOWP_RAW,
"Snore": SNORE_RAW,
"SpO2": SPO2_RAW,
"5_class": FIVE_CLASS_RAW
},
"LabelInput": {
"SA Label": "SA Label_Raw"
},
"StartTime": "StartTime_Raw",
"ChannelSave": {
"Effort Tho": "Effort Tho_Sync_",
"Effort Abd": "Effort Abd_Sync_",
"Flow T": "Flow T_Sync_",
"Flow P": "Flow P_Sync_",
"Snore": "Snore_Sync_",
"SpO2": "SpO2_Sync_",
"5_class": "5_class_Sync_"
"Effort Tho": THO_SYNC,
"Effort Abd": ABD_SYNC,
"Flow T": FLOWT_SYNC,
"Flow P": FLOWP_SYNC,
"Snore": SNORE_SYNC,
"SpO2": SPO2_SYNC,
"5_class": FIVE_CLASS_SYNC
},
"LabelSave": {
"SA Label": "SA Label_Sync"
@ -249,7 +228,6 @@ class ConfigParams:
"StartTime": ENDSWITH_TXT
},
}
CUT_PSG_SAVE_ECG_ALIGNINFO_FILENAME: str = "Align_info"
CUT_PSG_SALABEL_EVENT: list = ["Hypopnea", "Central apnea", "Obstructive apnea", "Mixed apnea"]

View File

@ -94,6 +94,10 @@ class Constants:
"Frequency_Not_In_Filename": "(数据频率不在文件名中)",
"Data_Not_Exist": "(数据不存在)",
"Model_File_Not_Exist": "(模型文件不存在)",
"Cut_Data_Length_not_Correct": "(切割数据时长度不正确)",
"Align_Label_SALabel_Format_not_Correct": "映射标签时SA Label中的文件格式不正确",
"Filename_Format_not_Correct": "(文件名格式不正确)",
"Method_Not_Exist": "(检测方法不存在)",
"Open_Data_Exception": "(打开数据异常)",
"Process_Exception": "(处理异常)",
@ -106,7 +110,9 @@ class Constants:
"Calculate_Correlation_Exception": "(计算相关性异常)",
"Correlation_Align_Exception": "(处理相关对齐异常)",
"PostProcess_Align_Exception": "(数据后处理异常)",
"Cut_Data_Exception": "(切割数据异常)",
"Align_Label_Exception": "(映射标签异常)",
"Get_File_and_Freq_Excepetion": "(检查文件是否存在并获取其数据采样率异常)",
"res_orgBcg_Not_Exist": "切割后orgBcg不存在",
"res_BCG_Not_Exist": "切割后BCG不存在",
@ -145,19 +151,6 @@ class Constants:
DETECT_RPEAK_PREDICT_FINISHED: str = "预测完成"
DETECT_RPEAK_PREDICT_FAILURE: str = "预测失败"
DETECT_RPEAK_FAILURE_REASON = {
"Data_Path_Not_Exist": "(数据路径不存在)",
"Read_Data_Exception": "(读取数据异常)",
"Method_Not_Exist": "(检测方法不存在)",
"Read_Method_Exception": "(读取方法异常)",
"Predict_Exception": "(峰值预测异常)",
"Raw_Data_Not_Exist": "(原始数据不存在)",
"Filter_Exception": "(滤波器异常)",
"Processed_Data_Not_Exist": "(处理后数据不存在)",
"Peak_Not_Exist": "(预测的峰值不存在)",
"Save_Exception": "(保存异常)"
}
DETECT_RPEAK_DATA_LENGTH_POINTS: str = "数据长度(点数):"
DETECT_RPEAK_DURATION_MIN: str = "数据时长(分钟):"
DETECT_RPEAK_PEAK_AMOUNT: str = "R峰个数"
@ -167,16 +160,6 @@ class Constants:
DETECT_RPEAK_PLOT_LABEL_INTERVAL: str = "Interval"
# 人工纠正
LABEL_CHECK_FAILURE_REASON = {
"Data_Path_Not_Exist": "(数据路径不存在)",
"Read_Data_Exception": "(读取数据异常)",
"Raw_Data_Not_Exist": "(原始数据不存在)",
"Filter_Exception": "(滤波器异常)",
"Processed_Data_Not_Exist": "(处理后数据不存在)",
"Peak_Not_Exist": "(峰值不存在)",
"Save_Exception": "(保存异常)"
}
LABEL_CHECK_PLOT_LABEL_SIGNAL: str = "Data_Processed"
LABEL_CHECK_PLOT_LABEL_PEAK_ORIGINAL: str = "Peaks_Original"
LABEL_CHECK_PLOT_LABEL_PEAK_CORRECTED: str = "Peaks_Corrected"
@ -250,6 +233,21 @@ class Constants:
PRECISELY_ALIGN_RECOVER_SCALE: str = "尺度恢复"
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 = "映射标签失败"
@ -315,32 +313,6 @@ class Constants:
"Save_Exception": "(保存异常)"
}
# 冗余数据切割和标签映射
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": "(保存异常)"
}
# 体动标注
ARTIFACT_LABEL_LOADING_ARCHIVE: str = "正在获取历史存档"
ARTIFACT_LABEL_ARCHIVE_EXIST: str = "找到历史存档,成功读取"