新增脚本filename_regulation_generator.py,有命名规范需要修改时,只需要修改ConfigParams.py的Filename类里面的变量的值,之后直接运行脚本filename_regulation_generator.py即可获取最新版本的数据结构化输入和输出命名规范.html

This commit is contained in:
2025-05-28 22:04:49 +08:00
parent ee4df5ee93
commit 13cf749a99
17 changed files with 1083 additions and 908 deletions

View File

@ -0,0 +1,291 @@
from markdown import markdown
from func.utils.ConfigParams import Filename, Params
markdown_text = f"""
# 文件命名规范
### 当一份数据被完整走完标注流程后,数据文件夹目录结构将会是:
.../{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}
|-{Filename.ARTIFACT_A}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.ARTIFACT_B}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.ARTIFACT_C}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_CSV}
|-{Filename.SQ_LABEL_10S}{Params.ENDSWITH_CSV}
|-{Filename.SQ_LABEL_30S}{Params.ENDSWITH_CSV}
|-{Filename.RESP_QUALITY_LABEL}{Params.ENDSWITH_TXT}
|-{Filename.THO_PEAK}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.SA_LABEL_CORRECTED}{Params.ENDSWITH_CSV}
|-{Filename.SA_LABEL_ADD}{Params.ENDSWITH_CSV}
|-{Filename.PRECISELY_ALIGN_INFO}{Params.ENDSWITH_TXT}
|-{Filename.APPROXIMATELY_ALIGN_INFO}{Params.ENDSWITH_CSV}
.../{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}
|-{Filename.BCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.ORGBCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.JPEAK_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
.../{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}
|-{Filename.ORGBCG_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.BCG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.JPEAK_REVISE}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.JPEAK_REVISE_CORRECTED}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
.../{Filename.PATH_ORGBCG_ORIGIN}/{Filename.PATH_SAMPID}
|-...
.../{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}
|-{Filename.ECG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.RPEAK_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.FIVE_CLASS_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.SA_LABEL_SYNC}{Params.ENDSWITH_CSV}
|-{Filename.ABD_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.THO_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.FLOWT_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.FLOWP_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.SNORE_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.SPO2_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
.../{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}
|-{Filename.ECG_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.ECG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.RPEAK_FINAL}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.RPEAK_FINAL_CORRECTED}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.FIVE_CLASS_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.SA_LABEL_RAW}{Params.ENDSWITH_CSV}
|-{Filename.ABD_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.THO_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.FLOWT_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.FLOWP_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.SNORE_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.SPO2_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}
|-{Filename.STARTTIME_RAW}{Params.ENDSWITH_TXT}
.../{Filename.PATH_PSG_ORIGIN}/{Filename.PATH_SAMPID}
|-...
.../{Filename.PATH_REVEIVE_ORIGIN}
|-...
.../{Filename.PATH_REPORT}
|-...
### 1 数据粗同步
输入:
原始OrgBCG信号`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ORGBCG_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始Tho信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.THO_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始Abd信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ABD_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
输出:
粗同步后的位置索引:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.APPROXIMATELY_ALIGN_INFO}{Params.ENDSWITH_CSV}`
### 2 预处理
输入:
原始OrgBCG信号`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ORGBCG_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始ECG信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ECG_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
输出:
滤波后的BCG信号`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.BCG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
滤波后的ECG信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ECG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
### 3 数据精同步
#### 3.1 算法定位
#### 3.1.1 R峰算法定位
输入:
滤波后的ECG信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ECG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
输出:
算法定位的R峰坐标`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.RPEAK_FINAL}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
#### 3.1.2 J峰算法定位
输入:
滤波后的BCG信号`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.BCG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
输出:
算法定位的J峰坐标`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.JPEAK_REVISE}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
#### 3.2 人工纠正
#### 3.2.1 R峰人工纠正
输入:
滤波后的ECG信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ECG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
算法定位的R峰坐标`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.RPEAK_FINAL}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
粗同步后的位置索引:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.APPROXIMATELY_ALIGN_INFO}{Params.ENDSWITH_CSV}`
输出:
人工纠正后的R峰坐标`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.RPEAK_FINAL_CORRECTED}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
#### 3.2.2 J峰人工纠正*
输入:
滤波后的BCG信号`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.BCG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
算法定位的J峰坐标`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.JPEAK_REVISE}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
粗同步后的位置索引:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.APPROXIMATELY_ALIGN_INFO}{Params.ENDSWITH_CSV}`
输出:
人工纠正后的J峰坐标`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.JPEAK_REVISE_CORRECTED}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
#### 3.3 数据片段起止对齐、数据采样率同步
输入:
滤波后的ECG信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ECG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
人工纠正后的R峰坐标`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.RPEAK_FINAL_CORRECTED}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
滤波后的BCG信号`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.BCG_FILTER}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
人工纠正后的J峰坐标`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.JPEAK_REVISE_CORRECTED}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始OrgBCG信号`./{Filename.PATH_ORGBCG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ORGBCG_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
粗同步后的位置索引:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.APPROXIMATELY_ALIGN_INFO}{Params.ENDSWITH_CSV}`
输出:
精同步对齐信息:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.PRECISELY_ALIGN_INFO}{Params.ENDSWITH_TXT}`
同步后的ECG信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.ECG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的R峰坐标`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.RPEAK_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的BCG信号`./{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.BCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的OrgBCG信号`./{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.ORGBCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的J峰坐标`./{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.JPEAK_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
#### 3.4、冗余数据切割、标签映射
输入:
精同步对齐信息:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.PRECISELY_ALIGN_INFO}{Params.ENDSWITH_TXT}`
原始的Flow T信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.FLOWT_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始的Flow P信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.FLOWP_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始的Tho信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.THO_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始的Abd信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.ABD_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始的SpO2信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.SPO2_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始的Snore信号`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.SNORE_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始的睡眠分期标签:`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.FIVE_CLASS_RAW}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
原始的睡眠呼吸暂停事件标签:`./{Filename.PATH_PSG_TEXT}/{Filename.PATH_SAMPID}/{Filename.SA_LABEL_RAW}{Params.ENDSWITH_CSV}`
输出:
同步后的Flow T信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.FLOWT_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Flow P信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.FLOWP_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Tho信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.THO_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Abd信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.ABD_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的SpO2信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.SPO2_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Snore信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.SNORE_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的睡眠分期标签:`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.FIVE_CLASS_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的睡眠呼吸暂停事件标签:`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.SA_LABEL_SYNC}{Params.ENDSWITH_CSV}`
### 4 体动标记
输入:
同步后的BCG信号`./{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.BCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的OrgBCG信号`./{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.ORGBCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
输出:
txt格式的体动标签`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.ARTIFACT_A}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
体动标签类型数量统计:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.ARTIFACT_B}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
csv格式的体动标签`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.ARTIFACT_C}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_CSV}`
### 5 质量评估
输入:
同步后的BCG信号`./{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.BCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
txt格式的体动标签`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.ARTIFACT_A}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
输出:
质量标签:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.SQ_LABEL_10S}{Params.ENDSWITH_CSV}`或`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.SQ_LABEL_30S}{Params.ENDSWITH_CSV}`
### 6 呼吸提取
输入:
同步后的OrgBCG信号`./{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.ORGBCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Tho信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.THO_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
txt格式的体动标签`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.ARTIFACT_A}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
输出:
呼吸可用性标签:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.RESP_QUALITY_LABEL}{Params.ENDSWITH_TXT}`
Tho信号呼吸间期标签`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.THO_PEAK}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
### 8 呼吸暂停事件标注
输入:
同步后的OrgBCG信号`./{Filename.PATH_ORGBCG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.ORGBCG_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
txt格式的体动标签`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.ARTIFACT_A}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Flow T信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.FLOWT_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Flow P信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.FLOWP_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Tho信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.THO_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的Abd信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.ABD_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的SpO2信号`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.SPO2_SYNC}{Filename.SUFFIX_FREQ}{Params.ENDSWITH_TXT}`
同步后的睡眠呼吸暂停事件标签:`./{Filename.PATH_PSG_ALIGNED}/{Filename.PATH_SAMPID}/{Filename.SA_LABEL_SYNC}{Params.ENDSWITH_CSV}`
输出:
修正后的呼吸暂停标签:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.SA_LABEL_CORRECTED}{Params.ENDSWITH_CSV}`
新增的呼吸暂停标签:`./{Filename.PATH_LABEL}/{Filename.PATH_SAMPID}/{Filename.SA_LABEL_ADD}{Params.ENDSWITH_CSV}`
"""
html = markdown(markdown_text)
with open('数据结构化输入和输出命名规范.html', 'w', encoding='utf-8') as file:
file.write(html)

View File

@ -15,9 +15,10 @@ from overrides import overrides
from pandas import read_csv, DataFrame, Series, concat
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.Filters.Preprocessing import Butterworth_for_ECG_PreProcess
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.utils.Result import Result
from ui.MainWindow.MainWindow_SA_label import Ui_MainWindow_SA_label
@ -98,36 +99,36 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.SA_LABEL_CONFIG_FILE_PATH).exists():
with open(ConfigParams.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.SA_LABEL_CONFIG_NEW_CONTENT, f)
if not Path(Params.SA_LABEL_CONFIG_FILE_PATH).exists():
with open(Params.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(Params.SA_LABEL_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.SA_LABEL_CONFIG_FILE_PATH, "r") as f:
with open(Params.SA_LABEL_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
Config.update({
"Path": {
"Input_OrgBCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
"Input_OrgBCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Input_Tho": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
"Input_Tho": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Input_Abd": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Input_FlowT": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
"Input_Abd": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Input_FlowP": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
"Input_FlowT": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Input_SpO2": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Input_Artifact": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
Path(str(self.sampID)))),
"Input_Label": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
"Input_FlowP": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Input_SpO2": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Input_Artifact": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Input_Label": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save_2": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Save_2": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID))))
},
"PlotEventIndex": 0,
@ -182,7 +183,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["FlowPFreq"] = self.ui.spinBox_input_freq_signal_FlowP.value()
self.config["InputConfig"]["SpO2Freq"] = self.ui.spinBox_input_freq_signal_SpO2.value()
with open(ConfigParams.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
with open(Params.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -193,46 +194,46 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_signal_OrgBCG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_SYNC +
Path(Filename.ORGBCG_SYNC +
str(self.ui.spinBox_input_freq_signal_OrgBCG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_Tho.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.THO_SYNC +
Path(Filename.THO_SYNC +
str(self.ui.spinBox_input_freq_signal_Tho.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_Abd.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.ABD_SYNC +
Path(Filename.ABD_SYNC +
str(self.ui.spinBox_input_freq_signal_Abd.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_FlowT.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.FLOWT_SYNC +
Path(Filename.FLOWT_SYNC +
str(self.ui.spinBox_input_freq_signal_FlowT.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_FlowP.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.FLOWP_SYNC +
Path(Filename.FLOWP_SYNC +
str(self.ui.spinBox_input_freq_signal_FlowP.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_SpO2.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.SPO2_SYNC +
Path(Filename.SPO2_SYNC +
str(self.ui.spinBox_input_freq_signal_SpO2.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
class MainWindow_SA_label(QMainWindow):
@ -305,31 +306,31 @@ class MainWindow_SA_label(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
self.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax2 = self.fig.add_subplot(self.gs[2], sharex=self.ax0)
self.ax2.grid(True)
self.ax2.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
self.ax2.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax3 = self.fig.add_subplot(self.gs[3], sharex=self.ax0)
self.ax3.grid(True)
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
self.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax4 = self.fig.add_subplot(self.gs[4], sharex=self.ax0)
self.ax4.grid(True)
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
self.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax5 = self.fig.add_subplot(self.gs[5], sharex=self.ax0)
self.ax5.grid(True)
self.ax5.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax5.xaxis.set_major_formatter(Params.FORMATTER)
self.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax6 = self.fig.add_subplot(self.gs[6], sharex=self.ax0)
self.ax6.grid(True)
self.ax6.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax6.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState)
@ -378,17 +379,17 @@ class MainWindow_SA_label(QMainWindow):
self.ui.checkBox_examineBySecond.clicked.connect(self.__slot_checkBox_examineBySecond__)
self.ui.checkBox_examineLabeled.clicked.connect(self.__slot_checkBox_examineLabeled__)
self.ui.pushButton_prev.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_PREV_SHORTCUT_KEY))
self.ui.pushButton_confirmLabel.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_CONFIRMLABEL_SHORTCUT_KEY))
self.ui.pushButton_next.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_NEXT_SHORTCUT_KEY))
self.ui.radioButton_OSA.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_OSA_SHORTCUT_KEY))
self.ui.radioButton_CSA.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_CSA_SHORTCUT_KEY))
self.ui.radioButton_MSA.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_MSA_SHORTCUT_KEY))
self.ui.radioButton_HPY.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_HPY_SHORTCUT_KEY))
self.ui.radioButton_1_class.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_1_CLASS_SHORTCUT_KEY))
self.ui.radioButton_2_class.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_2_CLASS_SHORTCUT_KEY))
self.ui.radioButton_3_class.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_RADIOBUTTON_3_CLASS_SHORTCUT_KEY))
self.ui.pushButton_quick_remark_input_waitingForTalk.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_QUICK_REMARK_WAITINGFORTALK_SHORTCUT_KEY))
self.ui.pushButton_prev.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_PREV_SHORTCUT_KEY))
self.ui.pushButton_confirmLabel.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_CONFIRMLABEL_SHORTCUT_KEY))
self.ui.pushButton_next.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_NEXT_SHORTCUT_KEY))
self.ui.radioButton_OSA.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_OSA_SHORTCUT_KEY))
self.ui.radioButton_CSA.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_CSA_SHORTCUT_KEY))
self.ui.radioButton_MSA.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_MSA_SHORTCUT_KEY))
self.ui.radioButton_HPY.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_HPY_SHORTCUT_KEY))
self.ui.radioButton_1_class.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_1_CLASS_SHORTCUT_KEY))
self.ui.radioButton_2_class.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_2_CLASS_SHORTCUT_KEY))
self.ui.radioButton_3_class.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_RADIOBUTTON_3_CLASS_SHORTCUT_KEY))
self.ui.pushButton_quick_remark_input_waitingForTalk.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_QUICK_REMARK_WAITINGFORTALK_SHORTCUT_KEY))
@overrides
def closeEvent(self, event):
@ -1003,37 +1004,37 @@ class MainWindow_SA_label(QMainWindow):
if self.ax0 is not None:
self.ax0.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax1 is not None:
self.ax1.clear()
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
self.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax2 is not None:
self.ax2.clear()
self.ax2.grid(True)
self.ax2.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
self.ax2.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax3 is not None:
self.ax3.clear()
self.ax3.grid(True)
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
self.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax4 is not None:
self.ax4.clear()
self.ax4.grid(True)
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
self.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax5 is not None:
self.ax5.clear()
self.ax5.grid(True)
self.ax5.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax5.xaxis.set_major_formatter(Params.FORMATTER)
self.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax6 is not None:
self.ax6.clear()
self.ax6.grid(True)
self.ax6.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax6.xaxis.set_major_formatter(Params.FORMATTER)
def on_xlim_change(self, event_ax):
# 获取当前x轴范围
@ -1162,7 +1163,7 @@ class MainWindow_SA_label(QMainWindow):
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
color='red',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Central apnea":
for ax in ax_:
@ -1170,7 +1171,7 @@ class MainWindow_SA_label(QMainWindow):
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
color='blue',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Mixed apnea":
for ax in ax_:
@ -1178,7 +1179,7 @@ class MainWindow_SA_label(QMainWindow):
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
color='gray',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Hypopnea":
for ax in ax_:
@ -1186,7 +1187,7 @@ class MainWindow_SA_label(QMainWindow):
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
color='pink',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
alpha=Params.SA_LABEL_TRANSPARENCY)
else:
if self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Obstructive apnea":
@ -1194,28 +1195,28 @@ class MainWindow_SA_label(QMainWindow):
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
color='red',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Central apnea":
for ax in ax_:
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
color='blue',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Mixed apnea":
for ax in ax_:
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
color='gray',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Hypopnea":
for ax in ax_:
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
color='pink',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY)
alpha=Params.SA_LABEL_TRANSPARENCY)
def pd_add_new_row(self, df, score: int, remark: str, correct_Start: int, correct_End: int, correct_EventsType: str,
isLabeled: int):
@ -1282,88 +1283,88 @@ class Data:
if Path(Config["Path"]["Input_Label"]).is_file():
Config["Path"]["Input_Label"] = str(Path(Config["Path"]["Input_Label"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], ConfigParams.ORGBCG_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_OrgBCG"] = result.data["path"]
Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], ConfigParams.THO_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Tho"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], ConfigParams.ABD_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], Filename.ABD_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Abd"] = result.data["path"]
Config["InputConfig"]["AbdFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_FlowT"], ConfigParams.FLOWT_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_FlowT"], Filename.FLOWT_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_FlowT"] = result.data["path"]
Config["InputConfig"]["FlowTFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_FlowP"], ConfigParams.FLOWP_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_FlowP"], Filename.FLOWP_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_FlowP"] = result.data["path"]
Config["InputConfig"]["FlowPFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_SpO2"], ConfigParams.SPO2_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_SpO2"], Filename.SPO2_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_SpO2"] = result.data["path"]
Config["InputConfig"]["SpO2Freq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_Artifact"], ConfigParams.ARTIFACT_A, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Artifact"], Filename.ARTIFACT_A, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Artifact"] = result.data["path"]
else:
return result
Config["Path"]["Input_Label"] = str(
Path(Config["Path"]["Input_Label"]) / Path(ConfigParams.SA_LABEL_SYNC + ConfigParams.ENDSWITH_CSV))
Path(Config["Path"]["Input_Label"]) / Path(Filename.SA_LABEL_SYNC + Params.ENDSWITH_CSV))
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(ConfigParams.SA_LABEL_CORRECTED + ConfigParams.ENDSWITH_CSV))
Path(Config["Path"]["Save"]) / Path(Filename.SA_LABEL_CORRECTED + Params.ENDSWITH_CSV))
Config["Path"]["Save_2"] = str(
Path(Config["Path"]["Save_2"]) / Path(ConfigParams.SA_LABEL_ADD + ConfigParams.ENDSWITH_CSV))
Path(Config["Path"]["Save_2"]) / Path(Filename.SA_LABEL_ADD + Params.ENDSWITH_CSV))
if not Path(Config["Path"]["Input_Artifact"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.ARTIFACT_A + "" +
Filename.ARTIFACT_A + "" +
Config["Path"]["Input_Artifact"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Label"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.SA_LABEL_SYNC + "" +
Filename.SA_LABEL_SYNC + "" +
Config["Path"]["Input_Label"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
try:
self.OrgBCG = read_csv(Config["Path"]["Input_OrgBCG"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Tho = read_csv(Config["Path"]["Input_Tho"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Abd = read_csv(Config["Path"]["Input_Abd"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.FlowT = read_csv(Config["Path"]["Input_FlowT"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.FlowP = read_csv(Config["Path"]["Input_FlowP"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.SpO2 = read_csv(Config["Path"]["Input_SpO2"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Artifact = read_csv(Config["Path"]["Input_Artifact"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.event_label = zeros(len(self.OrgBCG) + (int(Config["AddSecond"]["Front"] + int(Config["AddSecond"]["Back"])) * Config["InputConfig"]["PlotFreq"]))
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE +
@ -1623,6 +1624,6 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
def __init__(self, canvas, parent):
super().__init__(canvas, parent)
self.action_Reset_Signal_and_Time = QAction('复原视图和时间', self)
self.action_Reset_Signal_and_Time.setFont(QFont(ConfigParams.FONT, 14))
self.action_Reset_Signal_and_Time.setFont(QFont(Params.FONT, 14))
self.action_Reset_Signal_and_Time.setCheckable(True)
self.insertAction(self._actions['home'], self.action_Reset_Signal_and_Time)

View File

@ -13,8 +13,9 @@ from pandas import read_csv, DataFrame
from scipy.signal import find_peaks, resample, butter, sosfiltfilt, correlate
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.utils.Result import Result
from ui.MainWindow.MainWindow_approximately_align import Ui_MainWindow_approximately_align
@ -95,11 +96,11 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH).exists():
with open(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT, f)
if not Path(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH).exists():
with open(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "r") as f:
with open(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
@ -108,15 +109,15 @@ class SettingWindow(QMainWindow):
Config.update({
"Path": {
"Input_orgBcg": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Input_orgBcg": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Input_Tho": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Input_Tho": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Input_Abd": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Input_Abd": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
Path(str(self.sampID)) / Path(ConfigParams.APPROXIMATELY_ALIGN_INFO +
ConfigParams.ENDSWITH_CSV)))
"Save": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)) / Path(Filename.APPROXIMATELY_ALIGN_INFO +
Params.ENDSWITH_CSV)))
},
"orgBcgConfig": {},
"PSGConfig": {}
@ -158,7 +159,7 @@ class SettingWindow(QMainWindow):
self.config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandpassLow.value()
self.config["Filter"]["BandPassHigh"] = self.ui.doubleSpinBox_bandpassHigh.value()
with open(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
with open(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -169,25 +170,25 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_RAW +
Path(Filename.ORGBCG_RAW +
str(self.ui.spinBox_input_orgBcg_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_Tho.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.THO_RAW +
Path(Filename.THO_RAW +
str(self.ui.spinBox_input_Tho_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_Abd.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ABD_RAW +
Path(Filename.ABD_RAW +
str(self.ui.spinBox_input_Abd_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
class MainWindow_approximately_align(QMainWindow):
@ -927,19 +928,19 @@ class Data:
if Path(Config["Path"]["Input_Abd"]).is_file():
Config["Path"]["Input_Abd"] = str(Path(Config["Path"]["Input_Abd"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], ConfigParams.ORGBCG_RAW, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_RAW, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_orgBcg"] = result.data["path"]
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], ConfigParams.THO_RAW, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_RAW, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Tho"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], ConfigParams.ABD_RAW, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Abd"], Filename.ABD_RAW, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Abd"] = result.data["path"]
Config["InputConfig"]["AbdFreq"] = result.data["freq"]
@ -948,13 +949,13 @@ class Data:
try:
self.raw_orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.raw_Tho = read_csv(Config["Path"]["Input_Tho"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.raw_Abd = read_csv(Config["Path"]["Input_Abd"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON[
@ -1115,7 +1116,7 @@ class Data:
# 计算互相关1/2
try:
# 计算因子
MULTIPLE_FACTOER = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Multiple_Factor"]
MULTIPLE_FACTOER = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Multiple_Factor"]
a = self.processed_downsample_Tho[
Config["PSGConfig"]["PreCut"]:len(self.processed_downsample_Tho) - Config["PSGConfig"][
"PostCut"]].copy()
@ -1209,8 +1210,8 @@ class Data:
epoch_min = response.data["epoch_min"]
epoch_max = response.data["epoch_max"]
temp_freq = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"]
window_epoch = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["CorrByEpoch"]["window_epoch"]
temp_freq = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"]
window_epoch = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["CorrByEpoch"]["window_epoch"]
tho_bias_list = []
abd_bias_list = []

View File

@ -9,15 +9,16 @@ from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication, QTableWidg
from matplotlib import gridspec, patches
from matplotlib.backends.backend_qt import NavigationToolbar2QT
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
from numpy import array, append
from numpy import array
from numpy.fft import fft, fftfreq
from overrides import overrides
from pandas import read_csv, DataFrame, concat
from scipy.signal import resample
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.utils.Result import Result
from ui.MainWindow.MainWindow_artifact_label import Ui_MainWindow_artifact_label
@ -78,26 +79,26 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH).exists():
with open(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.ARTIFACT_LABEL_CONFIG_NEW_CONTENT, f)
if not Path(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH).exists():
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(Params.ARTIFACT_LABEL_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH, "r") as f:
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
Config.update({
"Path": {
"Input_orgBcg": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
"Input_orgBcg": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Input_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
"Input_BCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Save_a": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Save_a": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save_b": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Save_b": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save_c": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Save_c": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID))))
}
})
@ -125,7 +126,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["orgBcgFreq"] = self.ui.spinBox_input_freq_orgBcg.value()
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.value()
with open(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -136,18 +137,18 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_SYNC +
Path(Filename.ORGBCG_SYNC +
str(self.ui.spinBox_input_freq_orgBcg.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_BCG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.BCG_SYNC +
Path(Filename.BCG_SYNC +
str(self.ui.spinBox_input_freq_BCG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
class MainWindow_artifact_label(QMainWindow):
@ -231,11 +232,11 @@ class MainWindow_artifact_label(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState)
@ -259,8 +260,8 @@ class MainWindow_artifact_label(QMainWindow):
self.ui.tableWidget_type_4.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.ui.tableWidget_type_5.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.ui.lineEdit_start_time.setValidator(ConfigParams.VALIDATOR_INTEGER)
self.ui.lineEdit_end_time.setValidator(ConfigParams.VALIDATOR_INTEGER)
self.ui.lineEdit_start_time.setValidator(Params.VALIDATOR_INTEGER)
self.ui.lineEdit_end_time.setValidator(Params.VALIDATOR_INTEGER)
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
self.ui.pushButton_type_1.clicked.connect(self.__slot_btn_label__)
@ -369,71 +370,71 @@ class MainWindow_artifact_label(QMainWindow):
if self.data.df_Artifact_a.iloc[i][1] == 1:
# 橙色,剧烈体动
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_DEEP_YELLOW)
self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_DEEP_YELLOW)
self.rectangles_ax1_patches.append(rectangle)
elif self.data.df_Artifact_a.iloc[i][1] == 2:
# 黄色,脉冲体动
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_YELLOW)
self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_YELLOW)
self.rectangles_ax1_patches.append(rectangle)
elif self.data.df_Artifact_a.iloc[i][1] == 3:
# 青色,常规体动
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_AQUA)
self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_AQUA)
self.rectangles_ax1_patches.append(rectangle)
elif self.data.df_Artifact_a.iloc[i][1] == 4:
# 紫色,疑似鼾声
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PURPLE_PINK)
self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PURPLE_PINK)
self.rectangles_ax1_patches.append(rectangle)
elif self.data.df_Artifact_a.iloc[i][1] == 5:
# 灰色,离床
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_DEEP_GREY)
self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
width=(self.data.df_Artifact_a.iloc[i][3] - self.data.df_Artifact_a.iloc[i][2]),
height=self.rect_up - self.rect_down,
fill=True, alpha=ConfigParams.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
fill=True, alpha=Params.ARTIFACT_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_DEEP_GREY)
self.rectangles_ax1_patches.append(rectangle)
for patch in self.rectangles_ax0_patches:
@ -927,12 +928,12 @@ class MainWindow_artifact_label(QMainWindow):
if self.ax0 is not None:
self.ax0.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax1 is not None:
self.ax1.clear()
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
def on_xlim_change(self, event_ax):
try:
@ -1205,14 +1206,14 @@ class Data:
if Path(Config["Path"]["Input_BCG"]).is_file():
Config["Path"]["Input_BCG"] = str(Path(Config["Path"]["Input_BCG"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], ConfigParams.ORGBCG_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_orgBcg"] = result.data["path"]
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], ConfigParams.BCG_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_BCG"] = result.data["path"]
Config["InputConfig"]["BCGFreq"] = result.data["freq"]
@ -1220,18 +1221,18 @@ class Data:
return result
Config["Path"]["Save_a"] = str(
Path(Config["Path"]["Save_a"]) / Path(ConfigParams.ARTIFACT_A + str(Config["InputConfig"]["UseFreq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Save_a"]) / Path(Filename.ARTIFACT_A + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_b"] = str(
Path(Config["Path"]["Save_b"]) / Path(ConfigParams.ARTIFACT_B + str(Config["InputConfig"]["UseFreq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Save_b"]) / Path(Filename.ARTIFACT_B + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_c"] = str(
Path(Config["Path"]["Save_c"]) / Path(ConfigParams.ARTIFACT_C + str(Config["InputConfig"]["UseFreq"]) + ConfigParams.ENDSWITH_CSV))
Path(Config["Path"]["Save_c"]) / Path(Filename.ARTIFACT_C + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_CSV))
try:
self.orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.BCG = read_csv(Config["Path"]["Input_BCG"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
@ -1265,7 +1266,7 @@ class Data:
return Result().success(info=Constants.ARCHIVE_NOT_EXIST)
else:
self.Artifact_a = read_csv(Config["Path"]["Save_a"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
try:
# 检查体动标签正确性,长度
@ -1311,7 +1312,7 @@ class Data:
self.df_Artifact_a.to_csv(Path(Config["Path"]["Save_a"]), header=False, index=False, sep='\n')
df_Artifact_b.to_csv(Path(Config["Path"]["Save_b"]), header=False, index=False, sep='\n')
self.df_Artifact_a.to_csv(Path(Config["Path"]["Save_c"]), index=False,
encoding=ConfigParams.GBK_ENCODING)
encoding=Params.GBK_ENCODING)
except Exception as e:
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON[
"Save_Exception"] + "\n" + format_exc())
@ -1325,19 +1326,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
super().__init__(canvas, parent)
# 初始化画框工具栏
self.action_Label_Artifact = QAction(Constants.ARTIFACT_LABEL_ACTION_LABEL, self)
self.action_Label_Artifact.setFont(QFont(ConfigParams.FONT, 14))
self.action_Label_Artifact.setFont(QFont(Params.FONT, 14))
self.action_Label_Artifact.setCheckable(True)
self.action_Label_Artifact.setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY))
Params.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY))
self.insertAction(self._actions['pan'], self.action_Label_Artifact)
self._actions['pan'].setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.ACTION_PAN_SHORTCUT_KEY))
Params.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY))
Params.ACTION_ZOOM_SHORTCUT_KEY))
# 用于存储事件连接ID
self.cid_mouse_press = None

View File

@ -16,8 +16,9 @@ from pandas import read_csv, DataFrame
from scipy.signal import resample, iirfilter, lfilter
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.utils.Result import Result
from ui.MainWindow.MainWindow_bcg_quality_label import Ui_MainWindow_bcg_quality_label
@ -83,22 +84,22 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.BCG_QUALITY_LABEL_CONFIG_FILE_PATH).exists():
with open(ConfigParams.BCG_QUALITY_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.BCG_QUALITY_LABEL_CONFIG_NEW_CONTENT, f)
if not Path(Params.BCG_QUALITY_LABEL_CONFIG_FILE_PATH).exists():
with open(Params.BCG_QUALITY_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(Params.BCG_QUALITY_LABEL_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.BCG_QUALITY_LABEL_CONFIG_FILE_PATH, "r") as f:
with open(Params.BCG_QUALITY_LABEL_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
Config.update({
"Path": {
"Input_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Input_Artifact": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Input_BCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Input_Artifact": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Save": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
},
"Mode": "30s",
@ -125,7 +126,7 @@ class SettingWindow(QMainWindow):
# 保存配置到文件
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_signal_BCG.value()
with open(ConfigParams.BCG_QUALITY_LABEL_CONFIG_FILE_PATH, "w") as f:
with open(Params.BCG_QUALITY_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -136,11 +137,11 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_signal_BCG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.BCG_SYNC +
Path(Filename.BCG_SYNC +
str(self.ui.spinBox_input_freq_signal_BCG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
def __update_mode__(self):
if self.ui.radioButton_30s_mode.isChecked():
@ -202,7 +203,7 @@ class MainWindow_bcg_quality_label(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState)
@ -252,8 +253,8 @@ class MainWindow_bcg_quality_label(QMainWindow):
self.ui.checkBox_type4.clicked.connect(self.__slot_checkBox__)
self.ui.checkBox_type5.clicked.connect(self.__slot_checkBox__)
self.ui.pushButton_prev.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.BCG_QUALITY_LABEL_BTN_PREV_SHORTCUT_KEY))
self.ui.pushButton_next.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.BCG_QUALITY_LABEL_BTN_NEXT_SHORTCUT_KEY))
self.ui.pushButton_prev.setShortcut(QCoreApplication.translate("MainWindow", Params.BCG_QUALITY_LABEL_BTN_PREV_SHORTCUT_KEY))
self.ui.pushButton_next.setShortcut(QCoreApplication.translate("MainWindow", Params.BCG_QUALITY_LABEL_BTN_NEXT_SHORTCUT_KEY))
@overrides
def closeEvent(self, event):
@ -844,7 +845,7 @@ class MainWindow_bcg_quality_label(QMainWindow):
if self.ax0 is not None:
self.ax0.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
def change_tablewidget_mode(self):
if Config["Mode"] == "10s":
@ -961,14 +962,14 @@ class Data():
if Path(Config["Path"]["Save"]).is_file():
Config["Path"]["Save"] = str(Path(Config["Path"]["Save"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], ConfigParams.BCG_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_BCG"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_Artifact"], ConfigParams.ARTIFACT_A, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Artifact"], Filename.ARTIFACT_A, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Artifact"] = result.data["path"]
else:
@ -976,19 +977,19 @@ class Data():
if Config["Mode"] == "30s":
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(ConfigParams.SQ_LABEL_30S + ConfigParams.ENDSWITH_CSV))
Path(Config["Path"]["Save"]) / Path(Filename.SQ_LABEL_30S + Params.ENDSWITH_CSV))
elif Config["Mode"] == "10s":
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(ConfigParams.SQ_LABEL_10S + ConfigParams.ENDSWITH_CSV))
Path(Config["Path"]["Save"]) / Path(Filename.SQ_LABEL_10S + Params.ENDSWITH_CSV))
else:
raise ValueError("模式不存在")
try:
self.BCG = read_csv(Config["Path"]["Input_BCG"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Artifact_a = read_csv(Config["Path"]["Input_Artifact"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
@ -1032,9 +1033,9 @@ class Data():
def get_archive(self):
if Config["Mode"] == "30s":
filename = ConfigParams.SQ_LABEL_30S
filename = Filename.SQ_LABEL_30S
elif Config["Mode"] == "10s":
filename = ConfigParams.SQ_LABEL_10S
filename = Filename.SQ_LABEL_10S
else:
raise ValueError("模式不存在")
@ -1050,7 +1051,7 @@ class Data():
return Result().success(info=filename + "" + Constants.ARCHIVE_NOT_EXIST)
else:
self.df_label = read_csv(Config["Path"]["Save"],
encoding=ConfigParams.GBK_ENCODING)
encoding=Params.GBK_ENCODING)
self.label = self.df_label[Constants.BCG_QUALITY_LABEL_COLUMN_LABEL].astype(str)
return Result().success(info=filename + "" + Constants.ARCHIVE_EXIST)
@ -1088,24 +1089,23 @@ class Data():
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
if self.df_label is None:
return Result().failure(info=ConfigParams.RESP_QUALITY_LABEL + Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
return Result().failure(info=Filename.RESP_QUALITY_LABEL + Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
if Config["Mode"] == "30s":
filename = ConfigParams.SQ_LABEL_30S
filename = Filename.SQ_LABEL_30S
elif Config["Mode"] == "10s":
filename = ConfigParams.SQ_LABEL_10S
filename = Filename.SQ_LABEL_10S
else:
raise ValueError("模式不存在")
try:
self.df_label.to_csv(Config["Path"]["Save"], index=False, encoding=ConfigParams.GBK_ENCODING)
self.df_label.to_csv(Config["Path"]["Save"], index=False, encoding=Params.GBK_ENCODING)
except Exception as e:
return Result().failure(info=filename + Constants.SAVE_FAILURE +
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
return Result().success(info=filename + Constants.SAVE_FINISHED + "标签为:" + str(label))
@staticmethod
def wipe_industrialFrequencyNoise(data, fs):
# 设计带阻滤波器Notch Filter来滤除49-51Hz的噪声

View File

@ -10,8 +10,9 @@ from overrides import overrides
from pandas import read_csv, DataFrame
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.utils.Result import Result
from ui.MainWindow.MainWindow_cut_PSG import Ui_MainWindow_cut_PSG
@ -62,9 +63,9 @@ class MainWindow_cut_PSG(QMainWindow):
Config.update({
"Path": {
"InputFolder": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT / Path(str(self.sampID))),
"SaveFolder": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Path(str(self.sampID))),
"InputAlignInfo": str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL / Path(str(self.sampID)))
"InputFolder": str(Path(self.root_path) / Filename.PATH_PSG_TEXT / Path(str(self.sampID))),
"SaveFolder": str(Path(self.root_path) / Filename.PATH_PSG_ALIGNED / Path(str(self.sampID))),
"InputAlignInfo": str(Path(self.root_path) / Filename.PATH_LABEL / Path(str(self.sampID)))
}
})
@ -94,11 +95,11 @@ class MainWindow_cut_PSG(QMainWindow):
ButtonState["Current"].update(ButtonState["Default"].copy())
def __read_config__(self):
if not Path(ConfigParams.CUT_PSG_CONFIG_FILE_PATH).exists():
with open(ConfigParams.CUT_PSG_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.CUT_PSG_CONFIG_NEW_CONTENT, f)
if not Path(Params.CUT_PSG_CONFIG_FILE_PATH).exists():
with open(Params.CUT_PSG_CONFIG_FILE_PATH, "w") as f:
dump(Params.CUT_PSG_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.CUT_PSG_CONFIG_FILE_PATH, "r") as f:
with open(Params.CUT_PSG_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
@ -231,9 +232,9 @@ class Data:
return Result().success(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FINISHED)
def open_file(self):
path = str(Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT / Path(str(self.sampID)))
path = str(Path(self.root_path) / Filename.PATH_PSG_TEXT / Path(str(self.sampID)))
for value in Config["ChannelInput"].values():
result = PublicFunc.examine_file(path, value, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(path, value, Params.ENDSWITH_TXT)
if not result.status:
return result
@ -242,20 +243,20 @@ class Data:
Config["Path"]["InputAlignInfo"] = str(
Path(Config["Path"]["InputAlignInfo"]) / Path(
ConfigParams.PRECISELY_ALIGN_INFO + ConfigParams.ENDSWITH_TXT))
Filename.PRECISELY_ALIGN_INFO + Params.ENDSWITH_TXT))
try:
for key in Config["ChannelInput"].keys():
self.raw[key] = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["ChannelInput"][key] + str(self.freq[key]) + Config["EndWith"][key])),
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.SALabel = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["LabelInput"]["SA Label"] + Config["EndWith"]["SA Label"])),
encoding=ConfigParams.GBK_ENCODING)
encoding=Params.GBK_ENCODING)
self.startTime = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["StartTime"] + Config["EndWith"]["StartTime"])),
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.alignInfo = read_csv(Path(Config["Path"]["InputAlignInfo"]),
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.alignInfo = literal_eval(self.alignInfo[0])
except Exception as e:
@ -290,7 +291,7 @@ class Data:
try:
# 读取SA标签
self.SALabel = self.SALabel.loc[:, ~self.SALabel.columns.str.contains("^Unnamed")]
self.SALabel = self.SALabel[self.SALabel["Event type"].isin(ConfigParams.CUT_PSG_SALABEL_EVENT)]
self.SALabel = self.SALabel[self.SALabel["Event type"].isin(Params.CUT_PSG_SALABEL_EVENT)]
self.SALabel["Duration"] = self.SALabel["Duration"].astype(str)
self.SALabel["Duration"] = self.SALabel["Duration"].str.replace(r' \(.*?\)', '', regex=True)
except Exception:

View File

@ -11,8 +11,9 @@ from overrides import overrides
from pandas import read_csv, DataFrame
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.utils.Result import Result
from func.utils.detect_Jpeak import preprocess, Jpeak_Detection
@ -59,20 +60,20 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH).exists():
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.DETECT_JPEAK_CONFIG_NEW_CONTENT, f)
if not Path(Params.DETECT_JPEAK_CONFIG_FILE_PATH).exists():
with open(Params.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
dump(Params.DETECT_JPEAK_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "r") as f:
with open(Params.DETECT_JPEAK_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
Config.update({
"Path": {
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Input": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Save": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID))))
}
})
@ -94,7 +95,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
self.config["ModelFolderPath"] = self.ui.plainTextEdit_deepmodel_path.toPlainText()
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
with open(Params.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -105,18 +106,18 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.BCG_FILTER +
Path(Filename.BCG_FILTER +
str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.JPEAK_REVISE +
Path(Filename.JPEAK_REVISE +
str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
class MainWindow_detect_Jpeak(QMainWindow):
@ -169,7 +170,7 @@ class MainWindow_detect_Jpeak(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState)
@ -355,7 +356,7 @@ class MainWindow_detect_Jpeak(QMainWindow):
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
total_rows = len(DataFrame(self.data.peak.reshape(-1)))
chunk_size = ConfigParams.DETECT_JPEAK_SAVE_CHUNK_SIZE
chunk_size = Params.DETECT_JPEAK_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
@ -379,7 +380,7 @@ class MainWindow_detect_Jpeak(QMainWindow):
def reset_axes(self):
self.ax0.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
def update_ui_comboBox_model(self, model_list):
self.ui.comboBox_model.clear()
@ -398,18 +399,18 @@ class Data:
if Path(Config["Path"]["Input"]).is_file():
Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input"], ConfigParams.BCG_FILTER, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input"], Filename.BCG_FILTER, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input"] = result.data["path"]
Config["InputConfig"]["Freq"] = result.data["freq"]
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(ConfigParams.JPEAK_REVISE + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Save"]) / Path(Filename.JPEAK_REVISE + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
else:
return result
try:
self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE +

View File

@ -11,8 +11,9 @@ from overrides import overrides
from pandas import read_csv, DataFrame
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.utils.Result import Result
from func.utils.detect_Rpeak import preprocess, Rpeak_Detection, get_method
@ -59,20 +60,20 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH).exists():
with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.DETECT_RPEAK_CONFIG_NEW_CONTENT, f)
if not Path(Params.DETECT_RPEAK_CONFIG_FILE_PATH).exists():
with open(Params.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
dump(Params.DETECT_RPEAK_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "r") as f:
with open(Params.DETECT_RPEAK_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
Config.update({
"Path": {
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Input": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Save": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID))))
}
})
@ -91,7 +92,7 @@ class SettingWindow(QMainWindow):
# 保存配置到文件
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
with open(Params.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -102,18 +103,18 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ECG_FILTER +
Path(Filename.ECG_FILTER +
str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.RPEAK_FINAL +
Path(Filename.RPEAK_FINAL +
str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
class MainWindow_detect_Rpeak(QMainWindow):
@ -166,11 +167,11 @@ class MainWindow_detect_Rpeak(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState)
@ -351,7 +352,7 @@ class MainWindow_detect_Rpeak(QMainWindow):
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
total_rows = len(DataFrame(self.data.peak.reshape(-1)))
chunk_size = ConfigParams.DETECT_RPEAK_SAVE_CHUNK_SIZE
chunk_size = Params.DETECT_RPEAK_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
@ -376,10 +377,10 @@ class MainWindow_detect_Rpeak(QMainWindow):
self.ax0.clear()
self.ax1.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
def update_ui_comboBox_method(self, method_list):
self.ui.comboBox_method.clear()
@ -399,18 +400,18 @@ class Data:
if Path(Config["Path"]["Input"]).is_file():
Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input"], ConfigParams.ECG_FILTER, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input"], Filename.ECG_FILTER, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input"] = result.data["path"]
Config["InputConfig"]["Freq"] = result.data["freq"]
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(ConfigParams.RPEAK_FINAL + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Save"]) / Path(Filename.RPEAK_FINAL + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
else:
return result
try:
self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE +

View File

@ -15,8 +15,9 @@ from pandas import read_csv, DataFrame
from scipy.signal import find_peaks
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.Filters.Preprocessing import data_preprocess_for_label_check
from func.utils.Result import Result
@ -69,11 +70,11 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH).exists():
with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.LABEL_CHECK_CONFIG_NEW_CONTENT, f)
if not Path(Params.LABEL_CHECK_CONFIG_FILE_PATH).exists():
with open(Params.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
dump(Params.LABEL_CHECK_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "r") as f:
with open(Params.LABEL_CHECK_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
@ -81,13 +82,13 @@ class SettingWindow(QMainWindow):
if self.mode == "BCG":
Config.update({
"Path": {
"Input_Signal": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Input_Peak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Input_Approximately_Align": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Input_Signal": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Input_Peak": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Input_Approximately_Align": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Save": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID))))
},
"Mode": self.mode
@ -95,13 +96,13 @@ class SettingWindow(QMainWindow):
elif self.mode == "ECG":
Config.update({
"Path": {
"Input_Signal": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Input_Peak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Input_Approximately_Align": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Input_Signal": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Input_Peak": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Input_Approximately_Align": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Save": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID))))
},
"Mode": self.mode
@ -147,7 +148,7 @@ class SettingWindow(QMainWindow):
# 保存配置到文件
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq_signal.value()
with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
with open(Params.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -159,47 +160,47 @@ class SettingWindow(QMainWindow):
if self.mode == "BCG":
self.ui.plainTextEdit_file_path_input_signal.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.BCG_FILTER +
Path(Filename.BCG_FILTER +
str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_peak.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.JPEAK_REVISE +
Path(Filename.JPEAK_REVISE +
str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.JPEAK_REVISE_CORRECTED +
Path(Filename.JPEAK_REVISE_CORRECTED +
str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
elif self.mode == "ECG":
self.ui.plainTextEdit_file_path_input_signal.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ECG_FILTER +
Path(Filename.ECG_FILTER +
str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_peak.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.RPEAK_FINAL +
Path(Filename.RPEAK_FINAL +
str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.RPEAK_FINAL_CORRECTED +
Path(Filename.RPEAK_FINAL_CORRECTED +
str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
else:
raise ValueError("模式不存在")
@ -281,11 +282,11 @@ class MainWindow_label_check(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0, sharey=self.ax0)
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState)
@ -638,12 +639,12 @@ class MainWindow_label_check(QMainWindow):
if self.ax0 is not None:
self.ax0.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax1 is not None:
self.ax1.clear()
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
def on_xlim_change(self, event_ax):
try:
@ -835,24 +836,24 @@ class MainWindow_label_check(QMainWindow):
if self.figToolbar.rect_patch_ax0 is None:
if self.is_left_button_pressed:
self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
elif self.is_right_button_pressed:
self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED)
alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED)
self.ax0.add_patch(self.figToolbar.rect_patch_ax0)
# 如果矩形patch不存在则创建一个新的
if self.figToolbar.rect_patch_ax1 is None:
if self.is_left_button_pressed:
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
elif self.is_right_button_pressed:
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED)
alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED)
self.ax1.add_patch(self.figToolbar.rect_patch_ax1)
# 更新矩形patch的位置和大小
@ -883,13 +884,13 @@ class Data:
def open_file(self):
if Config["Mode"] == "BCG":
signal = ConfigParams.BCG_FILTER
peak = ConfigParams.JPEAK_REVISE
save = ConfigParams.JPEAK_REVISE_CORRECTED
signal = Filename.BCG_FILTER
peak = Filename.JPEAK_REVISE
save = Filename.JPEAK_REVISE_CORRECTED
elif Config["Mode"] == "ECG":
signal = ConfigParams.ECG_FILTER
peak = ConfigParams.RPEAK_FINAL
save = ConfigParams.RPEAK_FINAL_CORRECTED
signal = Filename.ECG_FILTER
peak = Filename.RPEAK_FINAL
save = Filename.RPEAK_FINAL_CORRECTED
else:
raise ValueError("模式不存在")
if Path(Config["Path"]["Input_Signal"]).is_file():
@ -901,7 +902,7 @@ class Data:
if Path(Config["Path"]["Save"]).is_file():
Config["Path"]["Save"] = str(Path(Config["Path"]["Save"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input_Signal"], signal, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Signal"], signal, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Signal"] = result.data["path"]
Config["InputConfig"]["Freq"] = result.data["freq"]
@ -909,12 +910,12 @@ class Data:
return result
Config["Path"]["Input_Peak"] = str(
Path(Config["Path"]["Input_Peak"]) / Path(peak + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Input_Peak"]) / Path(peak + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Input_Approximately_Align"] = str(
Path(Config["Path"]["Input_Approximately_Align"]) / Path(
ConfigParams.APPROXIMATELY_ALIGN_INFO + ConfigParams.ENDSWITH_CSV))
Filename.APPROXIMATELY_ALIGN_INFO + Params.ENDSWITH_CSV))
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(save + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Save"]) / Path(save + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
if not Path(Config["Path"]["Input_Peak"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
@ -923,16 +924,16 @@ class Data:
Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.APPROXIMATELY_ALIGN_INFO + "" +
Filename.APPROXIMATELY_ALIGN_INFO + "" +
Config["Path"]["Input_Approximately_Align"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
try:
self.raw_data = read_csv(Config["Path"]["Input_Signal"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.original_peak = read_csv(Config["Path"]["Input_Peak"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE +
@ -967,7 +968,7 @@ class Data:
return Result().success(info=Constants.ARCHIVE_NOT_EXIST)
else:
self.corrected_peak = read_csv(Config["Path"]["Save"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
return Result().success(info=Constants.ARCHIVE_EXIST)
@ -1017,19 +1018,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
super().__init__(canvas, parent)
# 初始化画框工具栏
self.action_Label_Multiple = QAction(Constants.LABEL_CHECK_ACTION_LABEL_MULTIPLE_NAME, self)
self.action_Label_Multiple.setFont(QFont(ConfigParams.FONT, 14))
self.action_Label_Multiple.setFont(QFont(Params.FONT, 14))
self.action_Label_Multiple.setCheckable(True)
self.action_Label_Multiple.setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY))
Params.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY))
self.insertAction(self._actions['pan'], self.action_Label_Multiple)
self._actions['pan'].setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.ACTION_PAN_SHORTCUT_KEY))
Params.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY))
Params.ACTION_ZOOM_SHORTCUT_KEY))
# 用于存储事件连接ID
self.cid_mouse_press = None

View File

@ -20,7 +20,8 @@ from func.Module_bcg_quality_label import MainWindow_bcg_quality_label
from func.Module_resp_quality_label import MainWindow_resp_quality_label
from func.Module_SA_label import MainWindow_SA_label
from func.utils.Constants import Constants, ConfigParams
from func.utils.ConfigParams import Filename, Params
from func.utils.Constants import Constants
use("QtAgg")
@ -54,7 +55,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.__read_config__()
self.ui.plainTextEdit_root_path.setPlainText(Config["Path"]["Root"])
self.seek_sampID(Path(Config["Path"]["Root"]) / Path(ConfigParams.PUBLIC_PATH_ORGBCG_TEXT))
self.seek_sampID(Path(Config["Path"]["Root"]) / Path(Filename.PATH_ORGBCG_TEXT))
self.approximately_align = None
self.preprocess = None
@ -86,18 +87,18 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
@staticmethod
def __read_config__():
if not Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).exists():
Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).parent.mkdir(parents=True, exist_ok=True)
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PUBLIC_CONFIG_NEW_CONTENT, f)
if not Path(Params.PUBLIC_CONFIG_FILE_PATH).exists():
Path(Params.PUBLIC_CONFIG_FILE_PATH).parent.mkdir(parents=True, exist_ok=True)
with open(Params.PUBLIC_CONFIG_FILE_PATH, "w") as f:
dump(Params.PUBLIC_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "r") as f:
with open(Params.PUBLIC_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
@staticmethod
def __write_config__():
with open(Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH), "w") as f:
with open(Path(Params.PUBLIC_CONFIG_FILE_PATH), "w") as f:
dump(Config, f)
def __slot_btn_open__(self):
@ -105,7 +106,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
file_dialog.setFileMode(QFileDialog.Directory)
file_dialog.setOption(QFileDialog.ShowDirsOnly, True)
if file_dialog.exec_() == QFileDialog.Accepted:
self.seek_sampID(Path(file_dialog.selectedFiles()[0]) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT)
self.seek_sampID(Path(file_dialog.selectedFiles()[0]) / Filename.PATH_ORGBCG_TEXT)
self.ui.plainTextEdit_root_path.setPlainText(file_dialog.selectedFiles()[0])
# 修改配置

View File

@ -17,8 +17,9 @@ from resampy import resample
from scipy.signal import find_peaks
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.utils.Result import Result
from ui.MainWindow.MainWindow_precisely_align import Ui_MainWindow_precisely_align
@ -102,40 +103,40 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH).exists():
with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PRECISELY_ALIGN_CONFIG_NEW_CONTENT, f)
if not Path(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH).exists():
with open(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(Params.PRECISELY_ALIGN_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "r") as f:
with open(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
Config.update({
"Path": {
"Input_OrgBCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Input_OrgBCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Input_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Input_BCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Input_Jpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Input_Jpeak": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Input_ECG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Input_ECG": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Input_Rpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Input_Rpeak": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Input_Approximately_Align": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Input_Approximately_Align": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save_AlignInfo": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
Path(str(self.sampID)))),
"Save_OrgBCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
"Save_AlignInfo": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save_OrgBCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Save_BCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
"Save_BCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Save_ECG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
"Save_ECG": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Save_Jpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Save_Rpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
"Save_Jpeak": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Save_Rpeak": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID))))
},
"Coordinate": {
@ -221,7 +222,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.value()
self.config["InputConfig"]["ECGFreq"] = self.ui.spinBox_input_freq_ECG.value()
with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
with open(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -232,60 +233,60 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_RAW +
Path(Filename.ORGBCG_RAW +
str(self.ui.spinBox_input_freq_orgBcg.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_BCG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.BCG_FILTER +
Path(Filename.BCG_FILTER +
str(self.ui.spinBox_input_freq_BCG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_ECG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ECG_FILTER +
Path(Filename.ECG_FILTER +
str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_orgBcg.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_SYNC +
Path(Filename.ORGBCG_SYNC +
str(self.ui.spinBox_input_freq_orgBcg.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_BCG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.BCG_SYNC +
Path(Filename.BCG_SYNC +
str(self.ui.spinBox_input_freq_BCG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_ECG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.ECG_SYNC +
Path(Filename.ECG_SYNC +
str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_Jpeak.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.JPEAK_SYNC +
Path(Filename.JPEAK_SYNC +
str(self.ui.spinBox_input_freq_BCG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_Rpeak.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.RPEAK_SYNC +
Path(Filename.RPEAK_SYNC +
str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
class MainWindow_precisely_align(QMainWindow):
@ -463,10 +464,10 @@ class MainWindow_precisely_align(QMainWindow):
self.fig.subplots_adjust(top=0.95, bottom=0.05, right=0.98, left=0.05, hspace=0.15, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0, sharey=self.ax0)
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
Jpeak = self.data.Jpeak[:-2]
Rpeak = self.data.Rpeak[:-2]
@ -500,16 +501,16 @@ class MainWindow_precisely_align(QMainWindow):
self.fig.subplots_adjust(top=0.88, bottom=0.05, right=0.98, left=0.05, hspace=0.15, wspace=0.15)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax1 = self.fig.add_subplot(self.gs[2])
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
self.ax2 = self.fig.add_subplot(self.gs[1])
self.ax2.grid(True)
self.ax2.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
self.ax3 = self.fig.add_subplot(self.gs[3])
self.ax3.grid(True)
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.set_title(
"front\ncorre_IIV: {}, corre_II: {}\nsame_sign_rate:{}, total_time_ratio: {}\nshift: {}, alignment offset: {} seconds\noffset_interval: {}, anchor_J: {}, anchor_R: {}".format(
@ -566,7 +567,7 @@ class MainWindow_precisely_align(QMainWindow):
self.fig.subplots_adjust(top=0.95, bottom=0.05, right=0.98, left=0.05, hspace=0, wspace=0)
self.ax4 = self.fig.add_subplot(self.gs[0])
self.ax4.grid(True)
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
self.ax4.set_title("offset correct")
self.ax4.plot(plot_element["cut_ECG"], color=Constants.PLOT_COLOR_GREEN, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_ECG)
@ -587,7 +588,7 @@ class MainWindow_precisely_align(QMainWindow):
self.fig.subplots_adjust(top=0.95, bottom=0.05, right=0.98, left=0.05, hspace=0, wspace=0)
self.ax4 = self.fig.add_subplot(self.gs[0])
self.ax4.grid(True)
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
self.ax4.set_title("result preview")
self.ax4.plot(self.data.cut_ECG, color=Constants.PLOT_COLOR_GREEN, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_ECG)
@ -839,7 +840,7 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.progressbar_update(self, 2, 6, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG, 0)
total_rows = len(DataFrame(self.data.res_orgBcg.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
chunk_size = Params.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save_OrgBCG"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
@ -861,7 +862,7 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.progressbar_update(self, 3, 6, Constants.PRECISELY_ALIGN_SAVING_RES_BCG, 0)
total_rows = len(DataFrame(self.data.res_BCG.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
chunk_size = Params.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save_BCG"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
@ -883,7 +884,7 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.progressbar_update(self, 4, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG, 0)
total_rows = len(DataFrame(self.data.cut_ECG.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
chunk_size = Params.PRECISELY_ALIGN_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save_ECG"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
@ -905,7 +906,7 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.progressbar_update(self, 5, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK, 0)
total_rows = len(DataFrame(self.data.cut_Jpeak.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
chunk_size = Params.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
with open(Config["Path"]["Save_Jpeak"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
@ -927,7 +928,7 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.progressbar_update(self, 6, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK, 0)
total_rows = len(DataFrame(self.data.cut_Rpeak.reshape(-1)))
chunk_size = ConfigParams.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
chunk_size = Params.PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE
with open(Config["Path"]["Save_Rpeak"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
@ -1014,23 +1015,23 @@ class MainWindow_precisely_align(QMainWindow):
if self.ax0 is not None:
self.ax0.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
if self.ax1 is not None:
self.ax1.clear()
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
if self.ax2 is not None:
self.ax2.clear()
self.ax2.grid(True)
self.ax2.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
if self.ax3 is not None:
self.ax3.clear()
self.ax3.grid(True)
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
if self.ax4 is not None:
self.ax4.clear()
self.ax4.grid(True)
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
def redraw_calculate_coordination(self, plot_element=None):
if plot_element is not None and plot_element["mode"] == "select":
@ -1327,26 +1328,26 @@ class MainWindow_precisely_align(QMainWindow):
if self.figToolbar.ax0_BCG_rectangle_front is None and self.is_left_button_pressed:
self.figToolbar.ax0_BCG_rectangle_front = patches.Rectangle((0, 0), 1, 1,
fill=True,
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
self.ax0.add_patch(self.figToolbar.ax0_BCG_rectangle_front)
if self.figToolbar.ax0_BCG_rectangle_back is None and self.is_left_button_pressed:
self.figToolbar.ax0_BCG_rectangle_back = patches.Rectangle((0, 0), 1, 1,
fill=True,
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
fill=True,
alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
self.ax0.add_patch(self.figToolbar.ax0_BCG_rectangle_back)
if self.figToolbar.ax1_ECG_rectangle_front is None and self.is_left_button_pressed:
self.figToolbar.ax1_ECG_rectangle_front = patches.Rectangle((0, 0), 1, 1,
fill=True,
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
self.ax1.add_patch(self.figToolbar.ax1_ECG_rectangle_front)
if self.figToolbar.ax1_ECG_rectangle_back is None and self.is_left_button_pressed:
self.figToolbar.ax1_ECG_rectangle_back = patches.Rectangle((0, 0), 1, 1,
fill=True,
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
fill=True,
alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
self.ax1.add_patch(self.figToolbar.ax1_ECG_rectangle_back)
if self.ui.radioButton_BCG_front.isChecked():
@ -1454,7 +1455,7 @@ class Data:
if Path(Config["Path"]["Input_Approximately_Align"]).is_file():
Config["Path"]["Input_Approximately_Align"] = str(Path(Config["Path"]["Input_Approximately_Align"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], ConfigParams.ORGBCG_RAW, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_RAW, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_OrgBCG"] = result.data["path"]
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
@ -1462,29 +1463,29 @@ class Data:
return result
Config["Path"]["Input_Approximately_Align"] = str(
Path(Config["Path"]["Input_Approximately_Align"]) / Path(
ConfigParams.APPROXIMATELY_ALIGN_INFO + ConfigParams.ENDSWITH_CSV))
Filename.APPROXIMATELY_ALIGN_INFO + Params.ENDSWITH_CSV))
Config["Path"]["Save_AlignInfo"] = str(
Path(Config["Path"]["Save_AlignInfo"]) / Path(
ConfigParams.PRECISELY_ALIGN_INFO + ConfigParams.ENDSWITH_TXT))
Filename.PRECISELY_ALIGN_INFO + Params.ENDSWITH_TXT))
Config["Path"]["Save_OrgBCG"] = str(
Path(Config["Path"]["Save_OrgBCG"]) / Path(
ConfigParams.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + ConfigParams.ENDSWITH_TXT))
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], ConfigParams.BCG_FILTER, ConfigParams.ENDSWITH_TXT)
Filename.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + Params.ENDSWITH_TXT))
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_FILTER, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_BCG"] = result.data["path"]
Config["InputConfig"]["BCGFreq"] = result.data["freq"]
else:
return result
Config["Path"]["Input_Jpeak"] = str(
Path(Config["Path"]["Input_Jpeak"]) / Path(ConfigParams.JPEAK_REVISE_CORRECTED + str(
Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Input_Jpeak"]) / Path(Filename.JPEAK_REVISE_CORRECTED + str(
Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_BCG"] = str(
Path(Config["Path"]["Save_BCG"]) / Path(
ConfigParams.BCG_SYNC + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
Filename.BCG_SYNC + str(Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_Jpeak"] = str(
Path(Config["Path"]["Save_Jpeak"]) / Path(
ConfigParams.JPEAK_SYNC + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], ConfigParams.ECG_FILTER, ConfigParams.ENDSWITH_TXT)
Filename.JPEAK_SYNC + str(Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], Filename.ECG_FILTER, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_ECG"] = result.data["path"]
Config["InputConfig"]["ECGFreq"] = result.data["freq"]
@ -1492,45 +1493,45 @@ class Data:
return result
Config["Path"]["Input_Rpeak"] = str(
Path(Config["Path"]["Input_Rpeak"]) / Path(
ConfigParams.RPEAK_FINAL_CORRECTED + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
Filename.RPEAK_FINAL_CORRECTED + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_ECG"] = str(
Path(Config["Path"]["Save_ECG"]) / Path(
ConfigParams.ECG_SYNC + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
Filename.ECG_SYNC + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_Rpeak"] = str(
Path(Config["Path"]["Save_Rpeak"]) / Path(
ConfigParams.RPEAK_SYNC + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
Filename.RPEAK_SYNC + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
if not Path(Config["Path"]["Input_Jpeak"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.JPEAK_REVISE_CORRECTED + "" +
Filename.JPEAK_REVISE_CORRECTED + "" +
Config["Path"]["Input_Jpeak"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Rpeak"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.RPEAK_FINAL_CORRECTED + "" +
Filename.RPEAK_FINAL_CORRECTED + "" +
Config["Path"]["Input_Rpeak"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.APPROXIMATELY_ALIGN_INFO + "" +
Filename.APPROXIMATELY_ALIGN_INFO + "" +
Config["Path"]["Input_Approximately_Align"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
try:
self.raw_orgBcg = read_csv(Config["Path"]["Input_OrgBCG"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.raw_BCG = read_csv(Config["Path"]["Input_BCG"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Jpeak = read_csv(Config["Path"]["Input_Jpeak"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.raw_ECG = read_csv(Config["Path"]["Input_ECG"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Rpeak = read_csv(Config["Path"]["Input_Rpeak"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.argmax_BCG = np_argmax(self.raw_BCG)
self.argmax_ECG = np_argmax(self.raw_ECG)
@ -2004,19 +2005,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
super().__init__(canvas, parent)
# 初始化画框工具栏
self.action_Get_Range = QAction(Constants.PRECISELY_ALIGN_ACTION_GET_RANGE_NAME, self)
self.action_Get_Range.setFont(QFont(ConfigParams.FONT, 14))
self.action_Get_Range.setFont(QFont(Params.FONT, 14))
self.action_Get_Range.setCheckable(True)
self.action_Get_Range.setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY))
Params.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY))
self.insertAction(self._actions['pan'], self.action_Get_Range)
self._actions['pan'].setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.ACTION_PAN_SHORTCUT_KEY))
Params.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate(
"MainWindow",
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY))
Params.ACTION_ZOOM_SHORTCUT_KEY))
# 用于存储事件连接ID
self.cid_mouse_press = None

View File

@ -12,8 +12,9 @@ from pandas import read_csv, DataFrame
from scipy.signal import resample
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.utils.Constants import Constants
from func.Filters.Preprocessing import Butterworth_for_BCG_PreProcess, Butterworth_for_ECG_PreProcess
from func.utils.Result import Result
@ -62,11 +63,11 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.PREPROCESS_CONFIG_FILE_PATH).exists():
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PREPROCESS_CONFIG_NEW_CONTENT, f)
if not Path(Params.PREPROCESS_CONFIG_FILE_PATH).exists():
with open(Params.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
dump(Params.PREPROCESS_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "r") as f:
with open(Params.PREPROCESS_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
@ -74,9 +75,9 @@ class SettingWindow(QMainWindow):
if self.mode == "BCG":
Config.update({
"Path": {
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Input": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
"Save": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID))))
},
"Mode": self.mode
@ -84,9 +85,9 @@ class SettingWindow(QMainWindow):
elif self.mode == "ECG":
Config.update({
"Path": {
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Input": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
"Save": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID))))
},
"Mode": self.mode
@ -111,7 +112,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
self.config["OutputConfig"]["Freq"] = self.ui.spinBox_output_freq.value()
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
with open(Params.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -123,33 +124,33 @@ class SettingWindow(QMainWindow):
if self.mode == "BCG":
self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_RAW +
Path(Filename.ORGBCG_RAW +
str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.BCG_FILTER +
Path(Filename.BCG_FILTER +
str(self.ui.spinBox_output_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
elif self.mode == "ECG":
self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ECG_RAW +
Path(Filename.ECG_RAW +
str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT /
Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.ECG_FILTER +
Path(Filename.ECG_FILTER +
str(self.ui.spinBox_output_freq.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
else:
raise ValueError("模式不存在")
@ -205,7 +206,7 @@ class MainWindow_preprocess(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState)
@ -364,7 +365,7 @@ class MainWindow_preprocess(QMainWindow):
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
total_rows = len(DataFrame(self.data.processed_data.reshape(-1)))
chunk_size = ConfigParams.PREPROCESS_SAVE_CHUNK_SIZE
chunk_size = Params.PREPROCESS_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
@ -389,7 +390,7 @@ class MainWindow_preprocess(QMainWindow):
if self.ax0 is not None:
self.ax0.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
class Data:
@ -400,28 +401,28 @@ class Data:
def open_file(self):
if Config["Mode"] == "BCG":
signal = ConfigParams.ORGBCG_RAW
save = ConfigParams.BCG_FILTER
signal = Filename.ORGBCG_RAW
save = Filename.BCG_FILTER
elif Config["Mode"] == "ECG":
signal = ConfigParams.ECG_RAW
save = ConfigParams.ECG_FILTER
signal = Filename.ECG_RAW
save = Filename.ECG_FILTER
else:
raise ValueError("模式不存在")
if Path(Config["Path"]["Input"]).is_file():
Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input"], signal, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input"], signal, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input"] = result.data["path"]
Config["InputConfig"]["Freq"] = result.data["freq"]
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(save + str(Config["OutputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Save"]) / Path(save + str(Config["OutputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
else:
return result
try:
self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE +

View File

@ -15,9 +15,9 @@ from pandas import read_csv, DataFrame
from scipy.signal import find_peaks, resample
from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc
from func.utils.Constants import Constants, ConfigParams
from func.Filters.Preprocessing import Butterworth_for_BCG_PreProcess, Butterworth_for_ECG_PreProcess
from func.utils.Constants import Constants
from func.utils.Result import Result
from func.utils.resp_quality_label import pre_process, get_slice, evaluate_quality
from func.utils.resp_quality_label_filter import get_bandpass_bcgsignal
@ -82,26 +82,26 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self):
if not Path(ConfigParams.RESP_QUALITY_LABEL_CONFIG_FILE_PATH).exists():
with open(ConfigParams.RESP_QUALITY_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.RESP_QUALITY_LABEL_CONFIG_NEW_CONTENT, f)
if not Path(Params.RESP_QUALITY_LABEL_CONFIG_FILE_PATH).exists():
with open(Params.RESP_QUALITY_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(Params.RESP_QUALITY_LABEL_CONFIG_NEW_CONTENT, f)
with open(ConfigParams.RESP_QUALITY_LABEL_CONFIG_FILE_PATH, "r") as f:
with open(Params.RESP_QUALITY_LABEL_CONFIG_FILE_PATH, "r") as f:
file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config)
self.config = file_config
Config.update({
"Path": {
"Input_OrgBCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
"Input_OrgBCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))),
"Input_Tho": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
"Input_Tho": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Input_Artifact": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Input_Artifact": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save_Resp_quality_label": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
Path(str(self.sampID)))),
"Save_Tho_peak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
"Save_Resp_quality_label": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Save_Tho_peak": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID))))
},
"CurrentPartNum": 1,
@ -133,7 +133,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["OrgBCGFreq"] = self.ui.spinBox_input_freq_signal_OrgBCG.value()
self.config["InputConfig"]["ThoFreq"] = self.ui.spinBox_input_freq_signal_Tho.value()
with open(ConfigParams.RESP_QUALITY_LABEL_CONFIG_FILE_PATH, "w") as f:
with open(Params.RESP_QUALITY_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(self.config, f)
self.close()
@ -144,18 +144,18 @@ class SettingWindow(QMainWindow):
def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_signal_OrgBCG.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED /
Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_SYNC +
Path(Filename.ORGBCG_SYNC +
str(self.ui.spinBox_input_freq_signal_OrgBCG.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_Tho.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) /
Path(ConfigParams.THO_SYNC +
Path(Filename.THO_SYNC +
str(self.ui.spinBox_input_freq_signal_Tho.value()) +
ConfigParams.ENDSWITH_TXT))))
Params.ENDSWITH_TXT))))
class MainWindow_resp_quality_label(QMainWindow):
@ -227,10 +227,10 @@ class MainWindow_resp_quality_label(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0.1, wspace=0)
self.ax0 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax1 = self.fig.add_subplot(self.gs[1])
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
# 初始化频谱画框
self.fig_spectrum = plt.figure(figsize=(12, 9), dpi=100)
@ -353,10 +353,10 @@ class MainWindow_resp_quality_label(QMainWindow):
try:
if Config["CurrentPartNum"] != Config["DataPartNum"]:
begin_OrgBCG = Config["CurrentOrgBCGIndex"]
end_OrgBCG = (Config["CurrentOrgBCGIndex"] + ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
end_OrgBCG = (Config["CurrentOrgBCGIndex"] + Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["OrgBCGUseFreq"]))
begin_Tho = Config["CurrentThoIndex"]
end_Tho = (Config["CurrentThoIndex"] + ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
end_Tho = (Config["CurrentThoIndex"] + Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
else:
begin_OrgBCG = Config["CurrentOrgBCGIndex"]
@ -428,7 +428,7 @@ class MainWindow_resp_quality_label(QMainWindow):
try:
if Config["CurrentPartNum"] != Config["DataPartNum"]:
begin_Tho = Config["CurrentThoIndex"]
end_Tho = (Config["CurrentThoIndex"] + ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
end_Tho = (Config["CurrentThoIndex"] + Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
elif Config["CurrentPartNum"] == Config["DataPartNum"]:
begin_Tho = Config["CurrentThoIndex"]
@ -730,8 +730,8 @@ class MainWindow_resp_quality_label(QMainWindow):
artifact_indices = []
for i in range(0, len(self.data.Artifact_a)):
if i + 3 < len(self.data.Artifact_a): # 防止索引越界
index0 = self.data.Artifact_a[i + 2] // (Config["InputConfig"]["OrgBCGUseFreq"] * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC) # 第三行(索引+2
index1 = self.data.Artifact_a[i + 3] // (Config["InputConfig"]["OrgBCGUseFreq"] * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC) # 第四行(索引+3
index0 = self.data.Artifact_a[i + 2] // (Config["InputConfig"]["OrgBCGUseFreq"] * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC) # 第三行(索引+2
index1 = self.data.Artifact_a[i + 3] // (Config["InputConfig"]["OrgBCGUseFreq"] * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC) # 第四行(索引+3
if index0 == index1:
artifact_indices.append(index0)
else:
@ -742,10 +742,10 @@ class MainWindow_resp_quality_label(QMainWindow):
# 数据切片预处理
BCG = pre_process(
get_slice(
self.data.OrgBCG_Processed, seg_idx, ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC, Config["InputConfig"]["OrgBCGUseFreq"]), Config["InputConfig"]["OrgBCGUseFreq"], ConfigParams.RESP_QUALITY_LABEL_PREPROCESS_FC)
self.data.OrgBCG_Processed, seg_idx, Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC, Config["InputConfig"]["OrgBCGUseFreq"]), Config["InputConfig"]["OrgBCGUseFreq"], Params.RESP_QUALITY_LABEL_PREPROCESS_FC)
THO = pre_process(
get_slice(
self.data.Tho_Processed, seg_idx, ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC, Config["InputConfig"]["ThoUseFreq"]), Config["InputConfig"]["ThoUseFreq"], ConfigParams.RESP_QUALITY_LABEL_PREPROCESS_FC)
self.data.Tho_Processed, seg_idx, Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC, Config["InputConfig"]["ThoUseFreq"]), Config["InputConfig"]["ThoUseFreq"], Params.RESP_QUALITY_LABEL_PREPROCESS_FC)
# 质量评估
# 有体动1 无体动0
@ -805,10 +805,10 @@ class MainWindow_resp_quality_label(QMainWindow):
PublicFunc.msgbox_output(self, Constants.RESP_QUALITY_LABEL_VIEWING_THE_FIRST_PART, Constants.MSGBOX_TYPE_INFO)
return
Config["CurrentPartNum"] = Config["CurrentPartNum"] - 1
Config["CurrentOrgBCGIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
Config["CurrentOrgBCGIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
result = self.__plot__()
if not result.status:
PublicFunc.text_output(self.ui, result.info, Constants.TIPS_TYPE_ERROR)
@ -836,10 +836,10 @@ class MainWindow_resp_quality_label(QMainWindow):
PublicFunc.msgbox_output(self, Constants.RESP_QUALITY_LABEL_VIEWING_THE_LAST_PART, Constants.MSGBOX_TYPE_INFO)
return
Config["CurrentPartNum"] = Config["CurrentPartNum"] + 1
Config["CurrentOrgBCGIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
Config["CurrentOrgBCGIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
result = self.__plot__()
if not result.status:
PublicFunc.text_output(self.ui, result.info, Constants.TIPS_TYPE_ERROR)
@ -870,17 +870,17 @@ class MainWindow_resp_quality_label(QMainWindow):
if sender == self.ui.tableWidget_labeled:
Config["CurrentPartNum"] = int(
self.ui.tableWidget_labeled.item(row, 0).text())
Config["CurrentOrgBCGIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
Config["CurrentOrgBCGIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
elif sender == self.ui.tableWidget_tobelabeled:
Config["CurrentPartNum"] = int(
self.ui.tableWidget_tobelabeled.item(row, 0).text())
Config["CurrentOrgBCGIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
Config["CurrentOrgBCGIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]))
else:
raise ValueError("发射信号不存在")
result = self.__plot__()
@ -956,11 +956,11 @@ class MainWindow_resp_quality_label(QMainWindow):
if self.ax0 is not None:
self.ax0.clear()
self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
if self.ax1 is not None:
self.ax1.clear()
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
if self.ax0_spectrum is not None:
self.ax0_spectrum.clear()
self.ax0_spectrum.grid(True)
@ -1093,13 +1093,13 @@ class MainWindow_resp_quality_label(QMainWindow):
self.is_left_button_pressed = False
if rect_left < Config["CurrentThoIndex"]:
rect_left = Config["CurrentThoIndex"]
elif rect_left >= (Config["CurrentThoIndex"] + ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"])):
elif rect_left >= (Config["CurrentThoIndex"] + Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"])):
rect_left = 0
rect_right = 0
if (rect_right >= Config["CurrentThoIndex"] + ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
if (rect_right >= Config["CurrentThoIndex"] + Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"])):
rect_right = (Config["CurrentThoIndex"] + ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
rect_right = (Config["CurrentThoIndex"] + Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"]) - 1)
elif rect_right < Config["CurrentThoIndex"]:
rect_left = 0
@ -1167,12 +1167,12 @@ class MainWindow_resp_quality_label(QMainWindow):
if self.figToolbar.rect_patch_ax1 is None:
if self.is_left_button_pressed:
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.RESP_QUALITY_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
alpha=Params.RESP_QUALITY_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK)
elif self.is_right_button_pressed:
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.RESP_QUALITY_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED)
alpha=Params.RESP_QUALITY_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED)
self.ax1.add_patch(self.figToolbar.rect_patch_ax1)
# 更新矩形patch的位置和大小
@ -1215,7 +1215,7 @@ class Data():
if Path(Config["Path"]["Save_Tho_peak"]).is_file():
Config["Path"]["Save_Tho_peak"] = str(Path(Config["Path"]["Save_Tho_peak"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], ConfigParams.THO_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Tho"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"]
@ -1223,11 +1223,11 @@ class Data():
return result
Config["Path"]["Save_Tho_peak"] = str(
Path(Config["Path"]["Save_Tho_peak"]) / Path(ConfigParams.THO_PEAK + str(Config["InputConfig"]["ThoUseFreq"]) + ConfigParams.ENDSWITH_TXT))
Path(Config["Path"]["Save_Tho_peak"]) / Path(Filename.THO_PEAK + str(Config["InputConfig"]["ThoUseFreq"]) + Params.ENDSWITH_TXT))
try:
self.Tho = read_csv(Config["Path"]["Input_Tho"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
@ -1256,7 +1256,7 @@ class Data():
return Result().failure(info=Constants.PREPROCESS_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
try:
self.Tho_Processed = pre_process(self.Tho, Config["InputConfig"]["ThoUseFreq"], ConfigParams.RESP_QUALITY_LABEL_PREPROCESS_FC)
self.Tho_Processed = pre_process(self.Tho, Config["InputConfig"]["ThoUseFreq"], Params.RESP_QUALITY_LABEL_PREPROCESS_FC)
except Exception as e:
return Result().failure(info=Constants.PREPROCESS_FAILURE +
Constants.FAILURE_REASON["Preprocess_Exception"] + "\n" + format_exc())
@ -1284,15 +1284,15 @@ class Data():
if self.Tho_peak is None:
return Result().failure(info=ConfigParams.THO_PEAK + Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
return Result().failure(info=Filename.THO_PEAK + Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
try:
DataFrame(self.Tho_peak).to_csv(Path(Config["Path"]["Save_Tho_peak"]), mode='w', index=False, header=False)
except Exception as e:
return Result().failure(info=ConfigParams.THO_PEAK + Constants.SAVE_FAILURE +
return Result().failure(info=Filename.THO_PEAK + Constants.SAVE_FAILURE +
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
return Result().success(info=ConfigParams.THO_PEAK + Constants.SAVE_FINISHED)
return Result().success(info=Filename.THO_PEAK + Constants.SAVE_FINISHED)
def open_file_label(self):
if Path(Config["Path"]["Input_OrgBCG"]).is_file():
@ -1306,21 +1306,21 @@ class Data():
if Path(Config["Path"]["Save_Tho_peak"]).is_file():
Config["Path"]["Save_Tho_peak"] = str(Path(Config["Path"]["Save_Tho_peak"]).parent)
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], ConfigParams.ORGBCG_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_OrgBCG"] = result.data["path"]
Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], ConfigParams.THO_SYNC, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Tho"], Filename.THO_SYNC, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Tho"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"]
else:
return result
result = PublicFunc.examine_file(Config["Path"]["Input_Artifact"], ConfigParams.ARTIFACT_A, ConfigParams.ENDSWITH_TXT)
result = PublicFunc.examine_file(Config["Path"]["Input_Artifact"], Filename.ARTIFACT_A, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Artifact"] = result.data["path"]
else:
@ -1328,27 +1328,27 @@ class Data():
Config["Path"]["Save_Resp_quality_label"] = str(
Path(Config["Path"]["Save_Resp_quality_label"]) / Path(
ConfigParams.RESP_QUALITY_LABEL + ConfigParams.ENDSWITH_TXT))
Filename.RESP_QUALITY_LABEL + Params.ENDSWITH_TXT))
Config["Path"]["Save_Tho_peak"] = str(
Path(Config["Path"]["Save_Tho_peak"]) / Path(
ConfigParams.THO_PEAK + str(Config["InputConfig"]["ThoUseFreq"]) + ConfigParams.ENDSWITH_TXT))
Filename.THO_PEAK + str(Config["InputConfig"]["ThoUseFreq"]) + Params.ENDSWITH_TXT))
try:
self.OrgBCG = read_csv(Config["Path"]["Input_OrgBCG"],
encoding=ConfigParams.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Tho = read_csv(Config["Path"]["Input_Tho"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
self.Artifact_a = read_csv(Config["Path"]["Input_Artifact"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
try:
Config["DataPartNum"] = len(self.OrgBCG) // (ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
Config["InputConfig"]["OrgBCGFreq"]) + 1
Config["DataPartNum"] = len(self.OrgBCG) // (Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
Config["InputConfig"]["OrgBCGFreq"]) + 1
if Config["DataPartNum"] == 0:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Data_Length_Not_Correct"])
except Exception as e:
@ -1382,24 +1382,24 @@ class Data():
def get_archive_resp_quality(self):
if not Path(Config["Path"]["Save_Resp_quality_label"]).exists():
self.resp_quality_label = full(Config["DataPartNum"], -1)
return Result().success(info=ConfigParams.RESP_QUALITY_LABEL + "" + Constants.ARCHIVE_NOT_EXIST)
return Result().success(info=Filename.RESP_QUALITY_LABEL + "" + Constants.ARCHIVE_NOT_EXIST)
else:
self.resp_quality_label = read_csv(Config["Path"]["Save_Resp_quality_label"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
return Result().success(info=ConfigParams.RESP_QUALITY_LABEL + "" + Constants.ARCHIVE_EXIST)
return Result().success(info=Filename.RESP_QUALITY_LABEL + "" + Constants.ARCHIVE_EXIST)
def get_archive_tho_peak(self):
if not Path(Config["Path"]["Save_Tho_peak"]).exists():
self.Tho_peak = array([]).astype(int)
self.Tho_peak_y = array([]).astype(int)
return Result().success(info=ConfigParams.RESP_QUALITY_LABEL + "" + Constants.ARCHIVE_NOT_EXIST)
return Result().success(info=Filename.RESP_QUALITY_LABEL + "" + Constants.ARCHIVE_NOT_EXIST)
else:
self.Tho_peak = read_csv(Config["Path"]["Save_Tho_peak"],
encoding=ConfigParams.UTF8_ENCODING,
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
return Result().success(info=ConfigParams.THO_PEAK + "" + Constants.ARCHIVE_EXIST)
return Result().success(info=Filename.THO_PEAK + "" + Constants.ARCHIVE_EXIST)
def resample_tho_and_OrgBCG(self):
if (self.OrgBCG is None) or (self.Tho is None):
@ -1431,7 +1431,7 @@ class Data():
try:
self.OrgBCG_Processed = self.OrgBCG.copy()
self.Tho_Processed = pre_process(self.Tho, Config["InputConfig"]["ThoUseFreq"], ConfigParams.RESP_QUALITY_LABEL_PREPROCESS_FC)
self.Tho_Processed = pre_process(self.Tho, Config["InputConfig"]["ThoUseFreq"], Params.RESP_QUALITY_LABEL_PREPROCESS_FC)
self.Tho_peak_y = [self.Tho_Processed[x] for x in (self.Tho_peak)]
except Exception as e:
return Result().failure(info=Constants.PREPROCESS_FAILURE +
@ -1441,7 +1441,7 @@ class Data():
def preprocess_getBDR(self, orgBcg_slice, THO_slice, mode):
orgBcg = pre_process(orgBcg_slice, int(Config["InputConfig"]["OrgBCGUseFreq"]),
ConfigParams.RESP_QUALITY_LABEL_PREPROCESS_FC)
Params.RESP_QUALITY_LABEL_PREPROCESS_FC)
if mode == "preset":
BDR, band_low, band_high, bcg_spectrum, bcg_freq, tho_spectrum, tho_freq = (
get_bandpass_bcgsignal(orgBcg, THO_slice, int(Config["InputConfig"]["OrgBCGUseFreq"]),
@ -1463,15 +1463,15 @@ class Data():
if self.resp_quality_label is None:
return Result().failure(info=ConfigParams.RESP_QUALITY_LABEL + Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
return Result().failure(info=Filename.RESP_QUALITY_LABEL + Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
try:
DataFrame(self.resp_quality_label).to_csv(Path(Config["Path"]["Save_Resp_quality_label"]), mode='w', index=False, header=False)
except Exception as e:
return Result().failure(info=ConfigParams.RESP_QUALITY_LABEL + Constants.SAVE_FAILURE +
return Result().failure(info=Filename.RESP_QUALITY_LABEL + Constants.SAVE_FAILURE +
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
return Result().success(info=ConfigParams.RESP_QUALITY_LABEL + Constants.SAVE_FINISHED)
return Result().success(info=Filename.RESP_QUALITY_LABEL + Constants.SAVE_FINISHED)
class CustomNavigationToolbar(NavigationToolbar2QT):
@ -1480,14 +1480,14 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
super().__init__(canvas, parent)
# 初始化画框工具栏
self.action_Label_Multiple = QAction(Constants.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME, self)
self.action_Label_Multiple.setFont(QFont(ConfigParams.FONT, 14))
self.action_Label_Multiple.setFont(QFont(Params.FONT, 14))
self.action_Label_Multiple.setCheckable(True)
self.action_Label_Multiple.setShortcut(QCoreApplication.translate("MainWindow",
ConfigParams.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY))
Params.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY))
self.insertAction(self._actions['pan'], self.action_Label_Multiple)
self._actions['pan'].setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.ACTION_ZOOM_SHORTCUT_KEY))
self._actions['pan'].setShortcut(QCoreApplication.translate("MainWindow", Params.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate("MainWindow", Params.ACTION_ZOOM_SHORTCUT_KEY))
# 用于存储事件连接ID
self.cid_mouse_press = None

View File

@ -2,35 +2,20 @@ from PySide6.QtGui import QIntValidator, QDoubleValidator
from matplotlib.ticker import FuncFormatter
class ConfigParams:
# 公共
PUBLIC_CONFIG_FILE_PATH: str = "./config/Config_public.yaml"
PUBLIC_PATH_ORGBCG_TEXT: str = "OrgBCG_Text"
PUBLIC_PATH_PSG_TEXT: str = "PSG_Text"
PUBLIC_PATH_ORGBCG_ALIGNED: str = "OrgBCG_Aligned"
PUBLIC_PATH_PSG_ALIGNED: str = "PSG_Aligned"
PUBLIC_PATH_LABEL: str = "Label"
PUBLIC_CONFIG_NEW_CONTENT = {
"Path": {
"Root": ""
}
}
UTF8_ENCODING: str = "utf-8"
# 目前用到这个编码的地方:
# <BCG的质量评估打标>里的保存和读取csv文件的地方注意的是读取原始数据时依然使用UTF-8
GBK_ENCODING: str = "gbk"
ENDSWITH_TXT: str = ".txt"
ENDSWITH_CSV: str = ".csv"
ENDSWITH_EDF: str = ".edf"
FORMATTER = FuncFormatter(lambda x, p: f"{x:.0f}")
ACTION_PAN_SHORTCUT_KEY: str = "X"
ACTION_ZOOM_SHORTCUT_KEY: str = "C"
FONT: str = "Microsoft YaHei UI"
VALIDATOR_INTEGER = QIntValidator(-2**31, 2**31 - 1)
VALIDATOR_DOUBLE = QDoubleValidator(-1e100, 1e100, 10)
class Filename:
# 文件命名
PATH_ORGBCG_TEXT: str = "OrgBCG_Text"
PATH_PSG_TEXT: str = "PSG_Text"
PATH_ORGBCG_ALIGNED: str = "OrgBCG_Aligned"
PATH_PSG_ALIGNED: str = "PSG_Aligned"
PATH_ORGBCG_ORIGIN: str = "OrgBCG_Origin"
PATH_PSG_ORIGIN: str = "PSG_Origin"
PATH_LABEL: str = "Label"
PATH_REVEIVE_ORIGIN: str = "Receive_Origin"
PATH_REPORT: str = "Report"
PATH_SAMPID: str = "<sampID>"
SUFFIX_FREQ: str = "采样率"
# Folder: OrgBCG_Text
ORGBCG_RAW: str = "OrgBCG_Raw_"
BCG_FILTER: str = "BCG_Filter_"
@ -82,6 +67,28 @@ class ConfigParams:
SQ_LABEL_10S: str = "SQ_label_10s"
SQ_LABEL_30S: str = "SQ_label_30s"
class Params:
# 公共
PUBLIC_CONFIG_FILE_PATH: str = "./config/Config_public.yaml"
PUBLIC_CONFIG_NEW_CONTENT = {
"Path": {
"Root": ""
}
}
UTF8_ENCODING: str = "utf-8"
GBK_ENCODING: str = "gbk"
ENDSWITH_TXT: str = ".txt"
ENDSWITH_CSV: str = ".csv"
ENDSWITH_EDF: str = ".edf"
FORMATTER = FuncFormatter(lambda x, p: f"{x:.0f}")
ACTION_PAN_SHORTCUT_KEY: str = "X"
ACTION_ZOOM_SHORTCUT_KEY: str = "C"
FONT: str = "Microsoft YaHei UI"
VALIDATOR_INTEGER = QIntValidator(-2**31, 2**31 - 1)
VALIDATOR_DOUBLE = QDoubleValidator(-1e100, 1e100, 10)
# 数据粗同步
APPROXIMATELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_approximately_align.yaml"
APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
@ -207,29 +214,29 @@ class ConfigParams:
CUT_PSG_CONFIG_NEW_CONTENT: dict = {
"ECGFreq": 1000,
"ChannelInput": {
"Effort Tho": THO_RAW,
"Effort Abd": ABD_RAW,
"Flow T": FLOWT_RAW,
"Flow P": FLOWP_RAW,
"Snore": SNORE_RAW,
"SpO2": SPO2_RAW,
"5_class": FIVE_CLASS_RAW
"Effort Tho": Filename.THO_RAW,
"Effort Abd": Filename.ABD_RAW,
"Flow T": Filename.FLOWT_RAW,
"Flow P": Filename.FLOWP_RAW,
"Snore": Filename.SNORE_RAW,
"SpO2": Filename.SPO2_RAW,
"5_class": Filename.FIVE_CLASS_RAW
},
"LabelInput": {
"SA Label": SA_LABEL_RAW
"SA Label": Filename.SA_LABEL_RAW
},
"StartTime": STARTTIME_RAW,
"StartTime": Filename.STARTTIME_RAW,
"ChannelSave": {
"Effort Tho": THO_SYNC,
"Effort Abd": ABD_SYNC,
"Flow T": FLOWT_SYNC,
"Flow P": FLOWP_SYNC,
"Snore": SNORE_SYNC,
"SpO2": SPO2_SYNC,
"5_class": FIVE_CLASS_SYNC
"Effort Tho": Filename.THO_SYNC,
"Effort Abd": Filename.ABD_SYNC,
"Flow T": Filename.FLOWT_SYNC,
"Flow P": Filename.FLOWP_SYNC,
"Snore": Filename.SNORE_SYNC,
"SpO2": Filename.SPO2_SYNC,
"5_class": Filename.FIVE_CLASS_SYNC
},
"LabelSave": {
"SA Label": SA_LABEL_SYNC
"SA Label": Filename.SA_LABEL_SYNC
},
"EndWith": {
"Effort Tho": ENDSWITH_TXT,
@ -335,7 +342,6 @@ class ConfigParams:
def __new__(cls):
raise TypeError("Constants class cannot be instantiated")
# 禁止修改常量
@classmethod
def __setattr__(cls, key, value):

View File

@ -1,4 +1,4 @@
from func.utils.ConfigParams import ConfigParams
from func.utils.ConfigParams import Params
class Constants:
@ -240,7 +240,7 @@ class Constants:
LABEL_CHECK_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
LABEL_CHECK_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
LABEL_CHECK_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无新增或删除点"
LABEL_CHECK_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({ConfigParams.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
LABEL_CHECK_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({Params.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
# 数据精同步
PRECISELY_ALIGN_PROCESSING_DATA: str = "正在处理数据"
@ -296,7 +296,7 @@ class Constants:
PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT: str = "Selected Point"
PRECISELY_ALIGN_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无有效点"
PRECISELY_ALIGN_RECOVER_SCALE: str = "尺度恢复"
PRECISELY_ALIGN_ACTION_GET_RANGE_NAME: str = f"设置范围({ConfigParams.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY})"
PRECISELY_ALIGN_ACTION_GET_RANGE_NAME: str = f"设置范围({Params.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY})"
# 冗余数据切割和标签映射
CUT_PSG_GETTING_FILE_AND_FREQ: str = "正在获取文件及其采样率"
@ -328,7 +328,7 @@ class Constants:
ARTIFACT_LABEL_MERGE: str = "当前所打标的片段距离附近片段不到2秒片段序号"
ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY: str = "体动被删除"
ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE: str = "需要被删除的体动不存在"
ARTIFACT_LABEL_ACTION_LABEL: str = f"标注体动({ConfigParams.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY})"
ARTIFACT_LABEL_ACTION_LABEL: str = f"标注体动({Params.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY})"
ARTIFACT_LABEL_LABELBTN_STYLE_1: str = """
QPushButton {
@ -444,7 +444,7 @@ class Constants:
RESP_QUALITY_LABEL_CUSTOM_FILTER_ARGS_ERROR: str = "OrgBCG带通滤波频率设置范围应为数字范围是0~1"
RESP_QUALITY_LABEL_AUTOLABEL_ARGS_ERROR: str = "人工标注阈值设置范围应为数字范围是0~1"
RESP_QUALITY_LABEL_CHECK_ARGS_QUESTION_CONTENT: str = "你确定要执行此操作吗,请确保参数输入正确"
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({ConfigParams.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({Params.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
RESP_QUALITY_LABEL_A_QUALITY: int = 1
RESP_QUALITY_LABEL_B_QUALITY: int = 0
RESP_QUALITY_LABEL_C_QUALITY: int = -1

View File

@ -0,0 +1,168 @@
<h1>文件命名规范</h1>
<h3>当一份数据被完整走完标注流程后,数据文件夹目录结构将会是:</h3>
<pre><code>.../Label/&lt;sampID&gt;
|-Artifact_a_采样率.txt
|-Artifact_b_采样率.txt
|-Artifact_c_采样率.csv
|-SQ_label_10s.csv
|-SQ_label_30s.csv
|-Resp_quality_label.txt
|-Tho_peak_采样率.txt
|-SA Label_corrected.csv
|-SA Label_add.csv
|-Precisely_Align_Info.txt
|-Approximately_Align_Info.csv
.../OrgBCG_Aligned/&lt;sampID&gt;
|-BCG_Sync_采样率.txt
|-OrgBCG_Sync_采样率.txt
|-Jpeak_Sync_采样率.txt
.../OrgBCG_Text/&lt;sampID&gt;
|-OrgBCG_Raw_采样率.txt
|-BCG_Filter_采样率.txt
|-Jpeak_revise_采样率.txt
|-Jpeak_revise_corrected_采样率.txt
.../OrgBCG_Origin/&lt;sampID&gt;
|-...
.../PSG_Aligned/&lt;sampID&gt;
|-ECG_Sync_采样率.txt
|-Rpeak_Sync_采样率.txt
|-5_class_Sync_采样率.txt
|-SA Label_Sync.csv
|-Effort Abd_Sync_采样率.txt
|-Effort Tho_Sync_采样率.txt
|-Flow T_Sync_采样率.txt
|-Flow P_Sync_采样率.txt
|-Snore_Sync_采样率.txt
|-SpO2_Sync_采样率.txt
.../PSG_Text/&lt;sampID&gt;
|-ECG II_Raw_采样率.txt
|-ECG_Filter_采样率.txt
|-Rpeak_final_采样率.txt
|-Rpeak_final_corrected_采样率.txt
|-5_class_Raw_采样率.txt
|-SA Label_Raw.csv
|-Effort Abd_Raw_采样率.txt
|-Effort Tho_Raw_采样率.txt
|-Flow T_Raw_采样率.txt
|-Flow P_Raw_采样率.txt
|-Snore_Raw_采样率.txt
|-SpO2_Raw_采样率.txt
|-StartTime_Raw.txt
.../PSG_Origin/&lt;sampID&gt;
|-...
.../Receive_Origin
|-...
.../Report
|-...
</code></pre>
<h3>1 数据粗同步</h3>
<p>输入:</p>
<p>原始OrgBCG信号<code>./OrgBCG_Text/&lt;sampID&gt;/OrgBCG_Raw_采样率.txt</code></p>
<p>原始Tho信号<code>./PSG_Text/&lt;sampID&gt;/Effort Tho_Raw_采样率.txt</code></p>
<p>原始Abd信号<code>./PSG_Text/&lt;sampID&gt;/Effort Abd_Raw_采样率.txt</code></p>
<p>输出:</p>
<p>粗同步后的位置索引:<code>./Label/&lt;sampID&gt;/Approximately_Align_Info.csv</code></p>
<h3>2 预处理</h3>
<p>输入:</p>
<p>原始OrgBCG信号<code>./OrgBCG_Text/&lt;sampID&gt;/OrgBCG_Raw_采样率.txt</code></p>
<p>原始ECG信号<code>./PSG_Text/&lt;sampID&gt;/ECG II_Raw_采样率.txt</code></p>
<p>输出:</p>
<p>滤波后的BCG信号<code>./OrgBCG_Text/&lt;sampID&gt;/BCG_Filter_采样率.txt</code></p>
<p>滤波后的ECG信号<code>./PSG_Text/&lt;sampID&gt;/ECG_Filter_采样率.txt</code></p>
<h3>3 数据精同步</h3>
<h4>3.1 算法定位</h4>
<h4>3.1.1 R峰算法定位</h4>
<p>输入:</p>
<p>滤波后的ECG信号<code>./PSG_Text/&lt;sampID&gt;/ECG_Filter_采样率.txt</code></p>
<p>输出:</p>
<p>算法定位的R峰坐标<code>./PSG_Text/&lt;sampID&gt;/Rpeak_final_采样率.txt</code></p>
<h4>3.1.2 J峰算法定位</h4>
<p>输入:</p>
<p>滤波后的BCG信号<code>./OrgBCG_Text/&lt;sampID&gt;/BCG_Filter_采样率.txt</code></p>
<p>输出:</p>
<p>算法定位的J峰坐标<code>./OrgBCG_Text/&lt;sampID&gt;/Jpeak_revise_采样率.txt</code></p>
<h4>3.2 人工纠正</h4>
<h4>3.2.1 R峰人工纠正</h4>
<p>输入:</p>
<p>滤波后的ECG信号<code>./PSG_Text/&lt;sampID&gt;/ECG_Filter_采样率.txt</code></p>
<p>算法定位的R峰坐标<code>./PSG_Text/&lt;sampID&gt;/Rpeak_final_采样率.txt</code></p>
<p>粗同步后的位置索引:<code>./Label/&lt;sampID&gt;/Approximately_Align_Info.csv</code></p>
<p>输出:</p>
<p>人工纠正后的R峰坐标<code>./PSG_Text/&lt;sampID&gt;/Rpeak_final_corrected_采样率.txt</code></p>
<h4>3.2.2 J峰人工纠正*</h4>
<p>输入:</p>
<p>滤波后的BCG信号<code>./OrgBCG_Text/&lt;sampID&gt;/BCG_Filter_采样率.txt</code></p>
<p>算法定位的J峰坐标<code>./OrgBCG_Text/&lt;sampID&gt;/Jpeak_revise_采样率.txt</code></p>
<p>粗同步后的位置索引:<code>./Label/&lt;sampID&gt;/Approximately_Align_Info.csv</code></p>
<p>输出:</p>
<p>人工纠正后的J峰坐标<code>./OrgBCG_Text/&lt;sampID&gt;/Jpeak_revise_corrected_采样率.txt</code></p>
<h4>3.3 数据片段起止对齐、数据采样率同步</h4>
<p>输入:</p>
<p>滤波后的ECG信号<code>./PSG_Text/&lt;sampID&gt;/ECG_Filter_采样率.txt</code></p>
<p>人工纠正后的R峰坐标<code>./PSG_Text/&lt;sampID&gt;/Rpeak_final_corrected_采样率.txt</code></p>
<p>滤波后的BCG信号<code>./OrgBCG_Text/&lt;sampID&gt;/BCG_Filter_采样率.txt</code></p>
<p>人工纠正后的J峰坐标<code>./OrgBCG_Text/&lt;sampID&gt;/Jpeak_revise_corrected_采样率.txt</code></p>
<p>原始OrgBCG信号<code>./OrgBCG_Text/&lt;sampID&gt;/OrgBCG_Raw_采样率.txt</code></p>
<p>粗同步后的位置索引:<code>./Label/&lt;sampID&gt;/Approximately_Align_Info.csv</code></p>
<p>输出:</p>
<p>精同步对齐信息:<code>./Label/&lt;sampID&gt;/Precisely_Align_Info.txt</code></p>
<p>同步后的ECG信号<code>./PSG_Aligned/&lt;sampID&gt;/ECG_Sync_采样率.txt</code></p>
<p>同步后的R峰坐标<code>./PSG_Aligned/&lt;sampID&gt;/Rpeak_Sync_采样率.txt</code></p>
<p>同步后的BCG信号<code>./OrgBCG_Aligned/&lt;sampID&gt;/BCG_Sync_采样率.txt</code></p>
<p>同步后的OrgBCG信号<code>./OrgBCG_Aligned/&lt;sampID&gt;/OrgBCG_Sync_采样率.txt</code></p>
<p>同步后的J峰坐标<code>./OrgBCG_Aligned/&lt;sampID&gt;/Jpeak_Sync_采样率.txt</code></p>
<h4>3.4、冗余数据切割、标签映射</h4>
<p>输入:</p>
<p>精同步对齐信息:<code>./Label/&lt;sampID&gt;/Precisely_Align_Info.txt</code></p>
<p>原始的Flow T信号<code>./PSG_Text/&lt;sampID&gt;/Flow T_Sync_采样率.txt</code></p>
<p>原始的Flow P信号<code>./PSG_Text/&lt;sampID&gt;/Flow P_Sync_采样率.txt</code></p>
<p>原始的Tho信号<code>./PSG_Text/&lt;sampID&gt;/Effort Tho_Sync_采样率.txt</code></p>
<p>原始的Abd信号<code>./PSG_Text/&lt;sampID&gt;/Effort Abd_Sync_采样率.txt</code></p>
<p>原始的SpO2信号<code>./PSG_Text/&lt;sampID&gt;/SpO2_Sync_采样率.txt</code></p>
<p>原始的Snore信号<code>./PSG_Text/&lt;sampID&gt;/Snore_Sync_采样率.txt</code></p>
<p>原始的睡眠分期标签:<code>./PSG_Text/&lt;sampID&gt;/5_class_Raw_采样率.txt</code></p>
<p>原始的睡眠呼吸暂停事件标签:<code>./PSG_Text/&lt;sampID&gt;/SA Label_Raw.csv</code></p>
<p>输出:</p>
<p>同步后的Flow T信号<code>./PSG_Aligned/&lt;sampID&gt;/Flow T_Sync_采样率.txt</code></p>
<p>同步后的Flow P信号<code>./PSG_Aligned/&lt;sampID&gt;/Flow P_Sync_采样率.txt</code></p>
<p>同步后的Tho信号<code>./PSG_Aligned/&lt;sampID&gt;/Effort Tho_Sync_采样率.txt</code></p>
<p>同步后的Abd信号<code>./PSG_Aligned/&lt;sampID&gt;/Effort Abd_Sync_采样率.txt</code></p>
<p>同步后的SpO2信号<code>./PSG_Aligned/&lt;sampID&gt;/SpO2_Sync_采样率.txt</code></p>
<p>同步后的Snore信号<code>./PSG_Aligned/&lt;sampID&gt;/Snore_Sync_采样率.txt</code></p>
<p>同步后的睡眠分期标签:<code>./PSG_Aligned/&lt;sampID&gt;/5_class_Sync_采样率.txt</code></p>
<p>同步后的睡眠呼吸暂停事件标签:<code>./PSG_Aligned/&lt;sampID&gt;/SA Label_Sync.csv</code></p>
<h3>4 体动标记</h3>
<p>输入:</p>
<p>同步后的BCG信号<code>./OrgBCG_Aligned/&lt;sampID&gt;/BCG_Sync_采样率.txt</code></p>
<p>同步后的OrgBCG信号<code>./OrgBCG_Aligned/&lt;sampID&gt;/OrgBCG_Sync_采样率.txt</code></p>
<p>输出:</p>
<p>txt格式的体动标签<code>./Label/&lt;sampID&gt;/Artifact_a_采样率.txt</code></p>
<p>体动标签类型数量统计:<code>./Label/&lt;sampID&gt;/Artifact_b_采样率.txt</code></p>
<p>csv格式的体动标签<code>./Label/&lt;sampID&gt;/Artifact_c_采样率.csv</code></p>
<h3>5 质量评估</h3>
<p>输入:</p>
<p>同步后的BCG信号<code>./OrgBCG_Aligned/&lt;sampID&gt;/BCG_Sync_采样率.txt</code></p>
<p>txt格式的体动标签<code>./Label/&lt;sampID&gt;/Artifact_a_采样率.txt</code></p>
<p>输出:</p>
<p>质量标签:<code>./Label/&lt;sampID&gt;/SQ_label_10s.csv</code><code>./Label/&lt;sampID&gt;/SQ_label_30s.csv</code></p>
<h3>6 呼吸提取</h3>
<p>输入:</p>
<p>同步后的OrgBCG信号<code>./OrgBCG_Aligned/&lt;sampID&gt;/OrgBCG_Sync_采样率.txt</code></p>
<p>同步后的Tho信号<code>./PSG_Aligned/&lt;sampID&gt;/Effort Tho_Sync_采样率.txt</code></p>
<p>txt格式的体动标签<code>./Label/&lt;sampID&gt;/Artifact_a_采样率.txt</code></p>
<p>输出:</p>
<p>呼吸可用性标签:<code>./Label/&lt;sampID&gt;/Resp_quality_label.txt</code></p>
<p>Tho信号呼吸间期标签<code>./Label/&lt;sampID&gt;/Tho_peak_采样率.txt</code></p>
<h3>8 呼吸暂停事件标注</h3>
<p>输入:</p>
<p>同步后的OrgBCG信号<code>./OrgBCG_Aligned/&lt;sampID&gt;/OrgBCG_Sync_采样率.txt</code></p>
<p>txt格式的体动标签<code>./Label/&lt;sampID&gt;/Artifact_a_采样率.txt</code></p>
<p>同步后的Flow T信号<code>./PSG_Aligned/&lt;sampID&gt;/Flow T_Sync_采样率.txt</code></p>
<p>同步后的Flow P信号<code>./PSG_Aligned/&lt;sampID&gt;/Flow P_Sync_采样率.txt</code></p>
<p>同步后的Tho信号<code>./PSG_Aligned/&lt;sampID&gt;/Effort Tho_Sync_采样率.txt</code></p>
<p>同步后的Abd信号<code>./PSG_Aligned/&lt;sampID&gt;/Effort Abd_Sync_采样率.txt</code></p>
<p>同步后的SpO2信号<code>./PSG_Aligned/&lt;sampID&gt;/SpO2_Sync_采样率.txt</code></p>
<p>同步后的睡眠呼吸暂停事件标签:<code>./PSG_Aligned/&lt;sampID&gt;/SA Label_Sync.csv</code></p>
<p>输出:</p>
<p>修正后的呼吸暂停标签:<code>./Label/&lt;sampID&gt;/SA Label_corrected.csv</code></p>
<p>新增的呼吸暂停标签:<code>./Label/&lt;sampID&gt;/SA Label_add.csv</code></p>

View File

@ -1,300 +0,0 @@
# 文件命名规范
### 当一份数据被完整走完标注流程后,数据文件夹目录结构将会是:
```
.../Label/<sampID>
|-Artifact_a_采样率.txt
|-Artifact_b_采样率.txt
|-Artifact_c_采样率.csv
|-SQ_label_10s.csv
|-SQ_label_30s.csv
|-Resp_quality_label.txt
|-Tho_peak_采样率.txt
|-SA Label_corrected.csv
|-SA Label_add.csv
|-Precisely_Align_info.txt
|-Approximately_Align_Info.csv
.../OrgBCG_Aligned/<sampID>
|-BCG_Sync_采样率.txt
|-OrgBCG_Sync_采样率.txt
|-Jpeak_Sync_采样率.txt
.../OrgBCG_Text/<sampID>
|-OrgBCG_Raw_采样率.txt
|-BCG_Filter_采样率.txt
|-Jpeak_revise_采样率.txt
|-Jpeak_revise_corrected_采样率.txt
.../OrgBCG_Origin/<sampID>
|-...
.../PSG_Aligned/<sampID>
|-ECG_Sync_采样率.txt
|-Rpeak_Sync_采样率.txt
|-5_class_Sync_采样率.txt
|-SA Label_Sync.csv
|-Effort Abd_Sync_采样率.txt
|-Effort Tho_Sync_采样率.txt
|-Flow T_Sync_采样率.txt
|-Flow P_Sync_采样率.txt
|-Snore_Sync_采样率.txt
|-SpO2_Sync_采样率.txt
.../PSG_Text/<sampID>
|-ECG II_Raw_采样率.txt
|-ECG_Filter_采样率.txt
|-Rpeak_final_采样率.txt
|-Rpeak_final_corrected_采样率.txt
|-5_class_Raw_采样率.txt
|-SA Label_Raw.csv
|-Effort Abd_Raw_采样率.txt
|-Effort Tho_Raw_采样率.txt
|-Flow T_Raw_采样率.txt
|-Flow P_Raw_采样率.txt
|-Snore_Raw_采样率.txt
|-SpO2_Raw_采样率.txt
|-StartTime_Raw.txt
.../PSG_Origin/<sampID>
|-...
.../Receive_Origin
|-...
.../Report
|-...
```
### 1 数据粗同步
输入:
原始orgBcg信号`./OrgBCG_Text/<sampID>/OrgBCG_Raw_采样率.txt`
原始PSG信号`./PSG_Text/<sampID>/Axxxxxxx.edf`
输出:
粗同步后的位置索引:`./Label/<sampID>/Approximately_Align_Info.csv`
### 2 预处理
输入:
原始orgBcg信号`./OrgBCG_Text/<sampID>/OrgBCG_Raw_采样率.txt`
原始ECG信号`./PSG_Text/<sampID>/ECG II_Raw_采样率.txt`
输出:
带通滤波BCG信号`./OrgBCG_Text/<sampID>/BCG_Filter_采样率.txt`
滤波后的ECG信号`./PSG_Text/<sampID>/ECG_Filter_采样率.txt`
### 3 数据精同步
#### 3.1 算法定位
#### 3.1.1 R峰算法定位
输入:
滤波后的ECG信号`./PSG_Text/<sampID>/ECG_Filter_采样率.txt`
输出:
算法定位的R峰坐标`./PSG_Text/<sampID>/Rpeak_final_采样率.txt`
#### 3.1.2 J峰算法定位
输入:
带通滤波BCG信号`./OrgBCG_Text/<sampID>/BCG_Filter_采样率.txt`
输出:
算法定位的J峰坐标`./OrgBCG_Text/<sampID>/Jpeak_revise_采样率.txt`
#### 3.2 人工纠正
#### 3.2.1 R峰人工纠正
输入:
滤波后的ECG信号`./PSG_Text/<sampID>/ECG_Filter_采样率.txt`
算法定位的R峰坐标`./PSG_Text/<sampID>/Rpeak_final_采样率.txt`
粗同步后的位置索引:`./Label/<sampID>/Approximately_Align_Info.csv`
输出:
人工纠正后的R峰坐标`./PSG_Text/<sampID>/Rpeak_final_corrected_采样率.txt`
#### 3.2.2 J峰人工纠正*
输入:
带通滤波BCG信号`./OrgBCG_Text/<sampID>/BCG_Filter_采样率.txt`
算法定位的J峰坐标`./OrgBCG_Text/<sampID>/Jpeak_revise_采样率.txt`
粗同步后的位置索引:`./Label/<sampID>/Approximately_Align_Info.csv`
输出:
人工纠正后的J峰坐标`./OrgBCG_Text/<sampID>/Jpeak_revise_corrected_采样率.txt`
#### 3.3 数据片段起止对齐、数据采样率同步
输入:
滤波后的ECG信号`./PSG_Text/<sampID>/ECG_Filter_采样率.txt`
人工纠正后的R峰坐标`./PSG_Text/<sampID>/Rpeak_final_corrected_采样率.txt`
带通滤波BCG信号`./OrgBCG_Text/<sampID>/BCG_Filter_采样率.txt`
人工纠正后的J峰坐标`./OrgBCG_Text/<sampID>/Jpeak_revise_corrected_采样率.txt`
原始orgBcg信号`./OrgBCG_Text/<sampID>/OrgBCG_Raw_采样率.txt`
粗同步后的位置索引:`./Label/<sampID>/Approximately_Align_Info.csv`
输出:
精同步对齐信息:`./Label/<sampID>/Precisely_Align_info.txt`
同步后的ECG信号`./PSG_Aligned/<sampID>/ECG_Sync_采样率.txt`
同步后的R峰坐标`./PSG_Aligned/<sampID>/Rpeak_Sync_采样率.txt`
同步后的BCG信号`./OrgBCG_Aligned/<sampID>/BCG_Sync_采样率.txt`
同步后的orgBcg信号`./OrgBCG_Aligned/<sampID>/OrgBCG_Sync_采样率.txt`
同步后的J峰坐标`./OrgBCG_Aligned/<sampID>/Jpeak_Sync_采样率.txt`
#### 3.4、冗余数据切割、标签映射
输入:
精同步对齐信息:`./Label/<sampID>/Precisely_Align_info.txt`
原始的其他PSG通道信号`./PSG_Text/<sampID>/通道名_Raw_采样率.txt`通道名包括Effort Abd, Effort Tho, Flow T, Flow P, Snore, SpO2
原始的睡眠分期标签:`./PSG_Text/<sampID>/5_class_Raw_采样率.txt`
原始的睡眠呼吸暂停事件标签:`./PSG_Text/<sampID>/SA Label_Raw.csv`
输出:
同步后的其他PSG通道信号`./PSG_Aligned/<sampID>/通道名_Sync_采样率.txt`通道名包括Effort Abd, Effort Tho, Flow T, Flow P, Snore, SpO2
同步后的睡眠分期标签:`./PSG_Aligned/<sampID>/5_class_Sync_采样率.txt`
同步后的睡眠呼吸暂停事件标签:`./PSG_Aligned/<sampID>/SA Label_Sync.csv`
### 4 体动标记
输入:
同步后的BCG信号`./OrgBCG_Aligned/<sampID>/BCG_Sync_采样率.txt`
同步后的orgBcg信号`./OrgBCG_Aligned/<sampID>/OrgBCG_Sync_采样率.txt`
输出:
txt格式的体动标签`./Label/<sampID>/Artifact_a_采样率.txt`
体动标签类型数量统计:`./Label/<sampID>/Artifact_b_采样率.txt`
csv格式的体动标签`./Label/<sampID>/Artifact_c_采样率.csv`
### 5 质量评估
输入:
同步后的BCG信号`./OrgBCG_Aligned/<sampID>/BCG_Sync_采样率.txt`
txt格式的体动标签`./Label/<sampID>/Artifact_a_采样率.txt`
输出:
质量标签:`./Label/<sampID>/SQ_label_10s.csv``./Label/<sampID>/SQ_label_30s.csv`
### 6 心搏定位数据标注
输入:
输出:
### 7 呼吸提取
输入:
同步后的orgBcg信号`./OrgBCG_Aligned/<sampID>/orgBcg_Sync_采样率.txt`
同步后的THO信号`./PSG_Aligned/<sampID>/Effort Tho_Sync_采样率.txt`
txt格式的体动标签`./Label/<sampID>/Artifact_a_采样率.txt`
输出:
呼吸可用性标签:`./Label/<sampID>/Resp_quality_label.txt`
THO信号呼吸间期标签`./Label/<sampID>/Tho_peak_采样率.txt`
### 8 呼吸暂停事件标注
输入:
同步后的orgBcg信号`./OrgBCG_Aligned/<sampID>/OrgBCG_Sync_采样率.txt`
txt格式的体动标签`./Label/<sampID>/Artifact_a_采样率.txt`
同步后的Flow T信号`./PSG_Aligned/<sampID>/Flow T_Sync_采样率.txt`
同步后的Flow P信号`./PSG_Aligned/<sampID>/Flow P_Sync_采样率.txt`
同步后的THO信号`./PSG_Aligned/<sampID>/Effort Tho_Sync_采样率.txt`
同步后的ABD信号`./PSG_Aligned/<sampID>/Effort Abd_Sync_采样率.txt`
同步后的SpO2信号`./PSG_Aligned/<sampID>/SpO2_Sync_采样率.txt`
同步后的呼吸暂停标签:`./PSG_Aligned/<sampID>/SA Label_Sync.csv`
输出:
修正后的呼吸暂停标签:`./Label/<sampID>/SA Label_corrected.csv`
新增的呼吸暂停标签:`./Label/<sampID>/SA Label_add.csv`