新增脚本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 pandas import read_csv, DataFrame, Series, concat
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.Filters.Preprocessing import Butterworth_for_ECG_PreProcess from func.Filters.Preprocessing import Butterworth_for_ECG_PreProcess
from func.utils.PublicFunc import PublicFunc 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.Result import Result
from ui.MainWindow.MainWindow_SA_label import Ui_MainWindow_SA_label 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) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.SA_LABEL_CONFIG_FILE_PATH).exists(): if not Path(Params.SA_LABEL_CONFIG_FILE_PATH).exists():
with open(ConfigParams.SA_LABEL_CONFIG_FILE_PATH, "w") as f: with open(Params.SA_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.SA_LABEL_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
Config.update({ Config.update({
"Path": { "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)))), 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)))), Path(str(self.sampID)))),
"Input_Abd": 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)))), Path(str(self.sampID)))),
"Input_FlowT": 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)))), Path(str(self.sampID)))),
"Input_FlowP": 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)))), Path(str(self.sampID)))),
"Input_SpO2": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED / "Input_SpO2": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))), 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)))), Path(str(self.sampID)))),
"Input_Label": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED / "Input_Label": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))), 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)))), 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)))) Path(str(self.sampID))))
}, },
"PlotEventIndex": 0, "PlotEventIndex": 0,
@ -182,7 +183,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["FlowPFreq"] = self.ui.spinBox_input_freq_signal_FlowP.value() self.config["InputConfig"]["FlowPFreq"] = self.ui.spinBox_input_freq_signal_FlowP.value()
self.config["InputConfig"]["SpO2Freq"] = self.ui.spinBox_input_freq_signal_SpO2.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) dump(self.config, f)
self.close() self.close()
@ -193,46 +194,46 @@ class SettingWindow(QMainWindow):
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_signal_OrgBCG.setPlainText( self.ui.plainTextEdit_file_path_input_signal_OrgBCG.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_SYNC + Path(Filename.ORGBCG_SYNC +
str(self.ui.spinBox_input_freq_signal_OrgBCG.value()) + str(self.ui.spinBox_input_freq_signal_OrgBCG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_Tho.setPlainText( self.ui.plainTextEdit_file_path_input_signal_Tho.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.THO_SYNC + Path(Filename.THO_SYNC +
str(self.ui.spinBox_input_freq_signal_Tho.value()) + str(self.ui.spinBox_input_freq_signal_Tho.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_Abd.setPlainText( self.ui.plainTextEdit_file_path_input_signal_Abd.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ABD_SYNC + Path(Filename.ABD_SYNC +
str(self.ui.spinBox_input_freq_signal_Abd.value()) + str(self.ui.spinBox_input_freq_signal_Abd.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_FlowT.setPlainText( self.ui.plainTextEdit_file_path_input_signal_FlowT.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.FLOWT_SYNC + Path(Filename.FLOWT_SYNC +
str(self.ui.spinBox_input_freq_signal_FlowT.value()) + str(self.ui.spinBox_input_freq_signal_FlowT.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_FlowP.setPlainText( self.ui.plainTextEdit_file_path_input_signal_FlowP.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.FLOWP_SYNC + Path(Filename.FLOWP_SYNC +
str(self.ui.spinBox_input_freq_signal_FlowP.value()) + str(self.ui.spinBox_input_freq_signal_FlowP.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_SpO2.setPlainText( self.ui.plainTextEdit_file_path_input_signal_SpO2.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.SPO2_SYNC + Path(Filename.SPO2_SYNC +
str(self.ui.spinBox_input_freq_signal_SpO2.value()) + str(self.ui.spinBox_input_freq_signal_SpO2.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
class MainWindow_SA_label(QMainWindow): 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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) 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.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0) self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
self.ax1.grid(True) 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.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax2 = self.fig.add_subplot(self.gs[2], sharex=self.ax0) self.ax2 = self.fig.add_subplot(self.gs[2], sharex=self.ax0)
self.ax2.grid(True) 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.ax2.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax3 = self.fig.add_subplot(self.gs[3], sharex=self.ax0) self.ax3 = self.fig.add_subplot(self.gs[3], sharex=self.ax0)
self.ax3.grid(True) 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.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax4 = self.fig.add_subplot(self.gs[4], sharex=self.ax0) self.ax4 = self.fig.add_subplot(self.gs[4], sharex=self.ax0)
self.ax4.grid(True) 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.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax5 = self.fig.add_subplot(self.gs[5], sharex=self.ax0) self.ax5 = self.fig.add_subplot(self.gs[5], sharex=self.ax0)
self.ax5.grid(True) 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.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax6 = self.fig.add_subplot(self.gs[6], sharex=self.ax0) self.ax6 = self.fig.add_subplot(self.gs[6], sharex=self.ax0)
self.ax6.grid(True) self.ax6.grid(True)
self.ax6.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax6.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState) 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_examineBySecond.clicked.connect(self.__slot_checkBox_examineBySecond__)
self.ui.checkBox_examineLabeled.clicked.connect(self.__slot_checkBox_examineLabeled__) 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_prev.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_PREV_SHORTCUT_KEY))
self.ui.pushButton_confirmLabel.setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.SA_LABEL_BTN_CONFIRMLABEL_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", ConfigParams.SA_LABEL_BTN_NEXT_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", ConfigParams.SA_LABEL_RADIOBUTTON_OSA_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", ConfigParams.SA_LABEL_RADIOBUTTON_CSA_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", ConfigParams.SA_LABEL_RADIOBUTTON_MSA_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", ConfigParams.SA_LABEL_RADIOBUTTON_HPY_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", ConfigParams.SA_LABEL_RADIOBUTTON_1_CLASS_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", ConfigParams.SA_LABEL_RADIOBUTTON_2_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", ConfigParams.SA_LABEL_RADIOBUTTON_3_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", ConfigParams.SA_LABEL_BTN_QUICK_REMARK_WAITINGFORTALK_SHORTCUT_KEY)) self.ui.pushButton_quick_remark_input_waitingForTalk.setShortcut(QCoreApplication.translate("MainWindow", Params.SA_LABEL_BTN_QUICK_REMARK_WAITINGFORTALK_SHORTCUT_KEY))
@overrides @overrides
def closeEvent(self, event): def closeEvent(self, event):
@ -1003,37 +1004,37 @@ class MainWindow_SA_label(QMainWindow):
if self.ax0 is not None: if self.ax0 is not None:
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE) self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax1 is not None: if self.ax1 is not None:
self.ax1.clear() self.ax1.clear()
self.ax1.grid(True) 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.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax2 is not None: if self.ax2 is not None:
self.ax2.clear() self.ax2.clear()
self.ax2.grid(True) 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.ax2.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax3 is not None: if self.ax3 is not None:
self.ax3.clear() self.ax3.clear()
self.ax3.grid(True) 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.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax4 is not None: if self.ax4 is not None:
self.ax4.clear() self.ax4.clear()
self.ax4.grid(True) 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.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax5 is not None: if self.ax5 is not None:
self.ax5.clear() self.ax5.clear()
self.ax5.grid(True) 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.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax6 is not None: if self.ax6 is not None:
self.ax6.clear() self.ax6.clear()
self.ax6.grid(True) 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): def on_xlim_change(self, event_ax):
# 获取当前x轴范围 # 获取当前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_Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
color='red', color='red',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY) alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[ elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Central apnea": Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Central apnea":
for ax in ax_: 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_Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
color='blue', color='blue',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY) alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[ elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Mixed apnea": Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Mixed apnea":
for ax in ax_: 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_Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
color='gray', color='gray',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY) alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[ elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Hypopnea": Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_EventsType"] == "Hypopnea":
for ax in ax_: 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_Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_End"],
color='pink', color='pink',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY) alpha=Params.SA_LABEL_TRANSPARENCY)
else: else:
if self.data.df_corrected.at[ if self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Obstructive apnea": 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"], ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
color='red', color='red',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY) alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[ elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Central apnea": Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Central apnea":
for ax in ax_: for ax in ax_:
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"], ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
color='blue', color='blue',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY) alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[ elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Mixed apnea": Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Mixed apnea":
for ax in ax_: for ax in ax_:
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"], ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
color='gray', color='gray',
alpha=ConfigParams.SA_LABEL_TRANSPARENCY) alpha=Params.SA_LABEL_TRANSPARENCY)
elif self.data.df_corrected.at[ elif self.data.df_corrected.at[
Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Hypopnea": Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Event type"] == "Hypopnea":
for ax in ax_: for ax in ax_:
ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"], ax.axvspan(self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "Start"],
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "End"],
color='pink', 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, def pd_add_new_row(self, df, score: int, remark: str, correct_Start: int, correct_End: int, correct_EventsType: str,
isLabeled: int): isLabeled: int):
@ -1282,87 +1283,87 @@ class Data:
if Path(Config["Path"]["Input_Label"]).is_file(): if Path(Config["Path"]["Input_Label"]).is_file():
Config["Path"]["Input_Label"] = str(Path(Config["Path"]["Input_Label"]).parent) 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: if result.status:
Config["Path"]["Input_OrgBCG"] = result.data["path"] Config["Path"]["Input_OrgBCG"] = result.data["path"]
Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"] Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_Tho"] = result.data["path"] Config["Path"]["Input_Tho"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"] Config["InputConfig"]["ThoFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_Abd"] = result.data["path"] Config["Path"]["Input_Abd"] = result.data["path"]
Config["InputConfig"]["AbdFreq"] = result.data["freq"] Config["InputConfig"]["AbdFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_FlowT"] = result.data["path"] Config["Path"]["Input_FlowT"] = result.data["path"]
Config["InputConfig"]["FlowTFreq"] = result.data["freq"] Config["InputConfig"]["FlowTFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_FlowP"] = result.data["path"] Config["Path"]["Input_FlowP"] = result.data["path"]
Config["InputConfig"]["FlowPFreq"] = result.data["freq"] Config["InputConfig"]["FlowPFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_SpO2"] = result.data["path"] Config["Path"]["Input_SpO2"] = result.data["path"]
Config["InputConfig"]["SpO2Freq"] = result.data["freq"] Config["InputConfig"]["SpO2Freq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_Artifact"] = result.data["path"] Config["Path"]["Input_Artifact"] = result.data["path"]
else: else:
return result return result
Config["Path"]["Input_Label"] = str( 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( 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( 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(): if not Path(Config["Path"]["Input_Artifact"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" + return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.ARTIFACT_A + "" + Filename.ARTIFACT_A + "" +
Config["Path"]["Input_Artifact"] + Config["Path"]["Input_Artifact"] +
Constants.FAILURE_REASON["Path_Not_Exist"]) Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Label"]).exists(): if not Path(Config["Path"]["Input_Label"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" + return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.SA_LABEL_SYNC + "" + Filename.SA_LABEL_SYNC + "" +
Config["Path"]["Input_Label"] + Config["Path"]["Input_Label"] +
Constants.FAILURE_REASON["Path_Not_Exist"]) Constants.FAILURE_REASON["Path_Not_Exist"])
try: try:
self.OrgBCG = read_csv(Config["Path"]["Input_OrgBCG"], self.OrgBCG = read_csv(Config["Path"]["Input_OrgBCG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Tho = read_csv(Config["Path"]["Input_Tho"], self.Tho = read_csv(Config["Path"]["Input_Tho"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Abd = read_csv(Config["Path"]["Input_Abd"], self.Abd = read_csv(Config["Path"]["Input_Abd"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.FlowT = read_csv(Config["Path"]["Input_FlowT"], self.FlowT = read_csv(Config["Path"]["Input_FlowT"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.FlowP = read_csv(Config["Path"]["Input_FlowP"], self.FlowP = read_csv(Config["Path"]["Input_FlowP"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.SpO2 = read_csv(Config["Path"]["Input_SpO2"], self.SpO2 = read_csv(Config["Path"]["Input_SpO2"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Artifact = read_csv(Config["Path"]["Input_Artifact"], self.Artifact = read_csv(Config["Path"]["Input_Artifact"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.event_label = zeros(len(self.OrgBCG) + (int(Config["AddSecond"]["Front"] + int(Config["AddSecond"]["Back"])) * Config["InputConfig"]["PlotFreq"])) self.event_label = zeros(len(self.OrgBCG) + (int(Config["AddSecond"]["Front"] + int(Config["AddSecond"]["Back"])) * Config["InputConfig"]["PlotFreq"]))
except Exception as e: except Exception as e:
@ -1623,6 +1624,6 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
def __init__(self, canvas, parent): def __init__(self, canvas, parent):
super().__init__(canvas, parent) super().__init__(canvas, parent)
self.action_Reset_Signal_and_Time = QAction('复原视图和时间', self) 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.action_Reset_Signal_and_Time.setCheckable(True)
self.insertAction(self._actions['home'], self.action_Reset_Signal_and_Time) 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 scipy.signal import find_peaks, resample, butter, sosfiltfilt, correlate
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc 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.Result import Result
from ui.MainWindow.MainWindow_approximately_align import Ui_MainWindow_approximately_align 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) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH).exists(): if not Path(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH).exists():
with open(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f: with open(Params.APPROXIMATELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
@ -108,15 +109,15 @@ class SettingWindow(QMainWindow):
Config.update({ Config.update({
"Path": { "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)))), 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)))), 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)))), 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)) / Path(ConfigParams.APPROXIMATELY_ALIGN_INFO + Path(str(self.sampID)) / Path(Filename.APPROXIMATELY_ALIGN_INFO +
ConfigParams.ENDSWITH_CSV))) Params.ENDSWITH_CSV)))
}, },
"orgBcgConfig": {}, "orgBcgConfig": {},
"PSGConfig": {} "PSGConfig": {}
@ -158,7 +159,7 @@ class SettingWindow(QMainWindow):
self.config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandpassLow.value() self.config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandpassLow.value()
self.config["Filter"]["BandPassHigh"] = self.ui.doubleSpinBox_bandpassHigh.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) dump(self.config, f)
self.close() self.close()
@ -169,25 +170,25 @@ class SettingWindow(QMainWindow):
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText( self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_RAW + Path(Filename.ORGBCG_RAW +
str(self.ui.spinBox_input_orgBcg_freq.value()) + str(self.ui.spinBox_input_orgBcg_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_Tho.setPlainText( self.ui.plainTextEdit_file_path_input_Tho.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.THO_RAW + Path(Filename.THO_RAW +
str(self.ui.spinBox_input_Tho_freq.value()) + str(self.ui.spinBox_input_Tho_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_Abd.setPlainText( self.ui.plainTextEdit_file_path_input_Abd.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ABD_RAW + Path(Filename.ABD_RAW +
str(self.ui.spinBox_input_Abd_freq.value()) + str(self.ui.spinBox_input_Abd_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
class MainWindow_approximately_align(QMainWindow): class MainWindow_approximately_align(QMainWindow):
@ -927,19 +928,19 @@ class Data:
if Path(Config["Path"]["Input_Abd"]).is_file(): if Path(Config["Path"]["Input_Abd"]).is_file():
Config["Path"]["Input_Abd"] = str(Path(Config["Path"]["Input_Abd"]).parent) 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: if result.status:
Config["Path"]["Input_orgBcg"] = result.data["path"] Config["Path"]["Input_orgBcg"] = result.data["path"]
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"] Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_Tho"] = result.data["path"] Config["Path"]["Input_Tho"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"] Config["InputConfig"]["ThoFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_Abd"] = result.data["path"] Config["Path"]["Input_Abd"] = result.data["path"]
Config["InputConfig"]["AbdFreq"] = result.data["freq"] Config["InputConfig"]["AbdFreq"] = result.data["freq"]
@ -948,13 +949,13 @@ class Data:
try: try:
self.raw_orgBcg = read_csv(Config["Path"]["Input_orgBcg"], self.raw_orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.raw_Tho = read_csv(Config["Path"]["Input_Tho"], self.raw_Tho = read_csv(Config["Path"]["Input_Tho"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.raw_Abd = read_csv(Config["Path"]["Input_Abd"], self.raw_Abd = read_csv(Config["Path"]["Input_Abd"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON[ return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON[
@ -1115,7 +1116,7 @@ class Data:
# 计算互相关1/2 # 计算互相关1/2
try: 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[ a = self.processed_downsample_Tho[
Config["PSGConfig"]["PreCut"]:len(self.processed_downsample_Tho) - Config["PSGConfig"][ Config["PSGConfig"]["PreCut"]:len(self.processed_downsample_Tho) - Config["PSGConfig"][
"PostCut"]].copy() "PostCut"]].copy()
@ -1209,8 +1210,8 @@ class Data:
epoch_min = response.data["epoch_min"] epoch_min = response.data["epoch_min"]
epoch_max = response.data["epoch_max"] epoch_max = response.data["epoch_max"]
temp_freq = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"] temp_freq = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["TempFrequency"]
window_epoch = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["CorrByEpoch"]["window_epoch"] window_epoch = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["CorrByEpoch"]["window_epoch"]
tho_bias_list = [] tho_bias_list = []
abd_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 import gridspec, patches
from matplotlib.backends.backend_qt import NavigationToolbar2QT from matplotlib.backends.backend_qt import NavigationToolbar2QT
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
from numpy import array, append from numpy import array
from numpy.fft import fft, fftfreq from numpy.fft import fft, fftfreq
from overrides import overrides from overrides import overrides
from pandas import read_csv, DataFrame, concat from pandas import read_csv, DataFrame, concat
from scipy.signal import resample from scipy.signal import resample
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc 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.Result import Result
from ui.MainWindow.MainWindow_artifact_label import Ui_MainWindow_artifact_label 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) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH).exists(): if not Path(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH).exists():
with open(ConfigParams.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f: with open(Params.ARTIFACT_LABEL_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.ARTIFACT_LABEL_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
Config.update({ Config.update({
"Path": { "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)))), 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)))), 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)))), 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)))), 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)))) 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"]["orgBcgFreq"] = self.ui.spinBox_input_freq_orgBcg.value()
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.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) dump(self.config, f)
self.close() self.close()
@ -136,18 +137,18 @@ class SettingWindow(QMainWindow):
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText( self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_SYNC + Path(Filename.ORGBCG_SYNC +
str(self.ui.spinBox_input_freq_orgBcg.value()) + str(self.ui.spinBox_input_freq_orgBcg.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_BCG.setPlainText( self.ui.plainTextEdit_file_path_input_BCG.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.BCG_SYNC + Path(Filename.BCG_SYNC +
str(self.ui.spinBox_input_freq_BCG.value()) + str(self.ui.spinBox_input_freq_BCG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
class MainWindow_artifact_label(QMainWindow): 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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) 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.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0) self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
self.ax1.grid(True) self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState) 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_4.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.ui.tableWidget_type_5.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_start_time.setValidator(Params.VALIDATOR_INTEGER)
self.ui.lineEdit_end_time.setValidator(ConfigParams.VALIDATOR_INTEGER) self.ui.lineEdit_end_time.setValidator(Params.VALIDATOR_INTEGER)
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__) self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
self.ui.pushButton_type_1.clicked.connect(self.__slot_btn_label__) self.ui.pushButton_type_1.clicked.connect(self.__slot_btn_label__)
@ -371,13 +372,13 @@ class MainWindow_artifact_label(QMainWindow):
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_DEEP_YELLOW)
self.rectangles_ax0_patches.append(rectangle) self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_DEEP_YELLOW)
self.rectangles_ax1_patches.append(rectangle) self.rectangles_ax1_patches.append(rectangle)
elif self.data.df_Artifact_a.iloc[i][1] == 2: elif self.data.df_Artifact_a.iloc[i][1] == 2:
@ -385,13 +386,13 @@ class MainWindow_artifact_label(QMainWindow):
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_YELLOW)
self.rectangles_ax0_patches.append(rectangle) self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_YELLOW)
self.rectangles_ax1_patches.append(rectangle) self.rectangles_ax1_patches.append(rectangle)
elif self.data.df_Artifact_a.iloc[i][1] == 3: elif self.data.df_Artifact_a.iloc[i][1] == 3:
@ -399,13 +400,13 @@ class MainWindow_artifact_label(QMainWindow):
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_AQUA)
self.rectangles_ax0_patches.append(rectangle) self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_AQUA)
self.rectangles_ax1_patches.append(rectangle) self.rectangles_ax1_patches.append(rectangle)
elif self.data.df_Artifact_a.iloc[i][1] == 4: elif self.data.df_Artifact_a.iloc[i][1] == 4:
@ -413,13 +414,13 @@ class MainWindow_artifact_label(QMainWindow):
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_PURPLE_PINK)
self.rectangles_ax0_patches.append(rectangle) self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_PURPLE_PINK)
self.rectangles_ax1_patches.append(rectangle) self.rectangles_ax1_patches.append(rectangle)
elif self.data.df_Artifact_a.iloc[i][1] == 5: elif self.data.df_Artifact_a.iloc[i][1] == 5:
@ -427,13 +428,13 @@ class MainWindow_artifact_label(QMainWindow):
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_DEEP_GREY)
self.rectangles_ax0_patches.append(rectangle) self.rectangles_ax0_patches.append(rectangle)
rectangle = patches.Rectangle((self.data.df_Artifact_a.iloc[i][2], self.rect_down), 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, 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) color=Constants.PLOT_COLOR_DEEP_GREY)
self.rectangles_ax1_patches.append(rectangle) self.rectangles_ax1_patches.append(rectangle)
for patch in self.rectangles_ax0_patches: for patch in self.rectangles_ax0_patches:
@ -927,12 +928,12 @@ class MainWindow_artifact_label(QMainWindow):
if self.ax0 is not None: if self.ax0 is not None:
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE) self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax1 is not None: if self.ax1 is not None:
self.ax1.clear() self.ax1.clear()
self.ax1.grid(True) 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): def on_xlim_change(self, event_ax):
try: try:
@ -1205,14 +1206,14 @@ class Data:
if Path(Config["Path"]["Input_BCG"]).is_file(): if Path(Config["Path"]["Input_BCG"]).is_file():
Config["Path"]["Input_BCG"] = str(Path(Config["Path"]["Input_BCG"]).parent) 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: if result.status:
Config["Path"]["Input_orgBcg"] = result.data["path"] Config["Path"]["Input_orgBcg"] = result.data["path"]
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"] Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_BCG"] = result.data["path"] Config["Path"]["Input_BCG"] = result.data["path"]
Config["InputConfig"]["BCGFreq"] = result.data["freq"] Config["InputConfig"]["BCGFreq"] = result.data["freq"]
@ -1220,18 +1221,18 @@ class Data:
return result return result
Config["Path"]["Save_a"] = str( 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( 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( 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: try:
self.orgBcg = read_csv(Config["Path"]["Input_orgBcg"], self.orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.BCG = read_csv(Config["Path"]["Input_BCG"], self.BCG = read_csv(Config["Path"]["Input_BCG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc()) 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) return Result().success(info=Constants.ARCHIVE_NOT_EXIST)
else: else:
self.Artifact_a = read_csv(Config["Path"]["Save_a"], self.Artifact_a = read_csv(Config["Path"]["Save_a"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
try: try:
# 检查体动标签正确性,长度 # 检查体动标签正确性,长度
@ -1311,7 +1312,7 @@ class Data:
self.df_Artifact_a.to_csv(Path(Config["Path"]["Save_a"]), header=False, index=False, sep='\n') 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') 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, 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: except Exception as e:
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON[ return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON[
"Save_Exception"] + "\n" + format_exc()) "Save_Exception"] + "\n" + format_exc())
@ -1325,19 +1326,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
super().__init__(canvas, parent) super().__init__(canvas, parent)
# 初始化画框工具栏 # 初始化画框工具栏
self.action_Label_Artifact = QAction(Constants.ARTIFACT_LABEL_ACTION_LABEL, self) 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.setCheckable(True)
self.action_Label_Artifact.setShortcut(QCoreApplication.translate( self.action_Label_Artifact.setShortcut(QCoreApplication.translate(
"MainWindow", "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.insertAction(self._actions['pan'], self.action_Label_Artifact)
self._actions['pan'].setShortcut(QCoreApplication.translate( self._actions['pan'].setShortcut(QCoreApplication.translate(
"MainWindow", "MainWindow",
ConfigParams.ACTION_PAN_SHORTCUT_KEY)) Params.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate( self._actions['zoom'].setShortcut(QCoreApplication.translate(
"MainWindow", "MainWindow",
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY)) Params.ACTION_ZOOM_SHORTCUT_KEY))
# 用于存储事件连接ID # 用于存储事件连接ID
self.cid_mouse_press = None 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 scipy.signal import resample, iirfilter, lfilter
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc 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.Result import Result
from ui.MainWindow.MainWindow_bcg_quality_label import Ui_MainWindow_bcg_quality_label 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) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.BCG_QUALITY_LABEL_CONFIG_FILE_PATH).exists(): if not Path(Params.BCG_QUALITY_LABEL_CONFIG_FILE_PATH).exists():
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(ConfigParams.BCG_QUALITY_LABEL_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
Config.update({ Config.update({
"Path": { "Path": {
"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)))), 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)))), 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)))), Path(str(self.sampID)))),
}, },
"Mode": "30s", "Mode": "30s",
@ -125,7 +126,7 @@ class SettingWindow(QMainWindow):
# 保存配置到文件 # 保存配置到文件
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_signal_BCG.value() 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) dump(self.config, f)
self.close() self.close()
@ -136,11 +137,11 @@ class SettingWindow(QMainWindow):
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_signal_BCG.setPlainText( self.ui.plainTextEdit_file_path_input_signal_BCG.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.BCG_SYNC + Path(Filename.BCG_SYNC +
str(self.ui.spinBox_input_freq_signal_BCG.value()) + str(self.ui.spinBox_input_freq_signal_BCG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
def __update_mode__(self): def __update_mode__(self):
if self.ui.radioButton_30s_mode.isChecked(): 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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState) 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_type4.clicked.connect(self.__slot_checkBox__)
self.ui.checkBox_type5.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_prev.setShortcut(QCoreApplication.translate("MainWindow", Params.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_next.setShortcut(QCoreApplication.translate("MainWindow", Params.BCG_QUALITY_LABEL_BTN_NEXT_SHORTCUT_KEY))
@overrides @overrides
def closeEvent(self, event): def closeEvent(self, event):
@ -844,7 +845,7 @@ class MainWindow_bcg_quality_label(QMainWindow):
if self.ax0 is not None: if self.ax0 is not None:
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
def change_tablewidget_mode(self): def change_tablewidget_mode(self):
if Config["Mode"] == "10s": if Config["Mode"] == "10s":
@ -961,14 +962,14 @@ class Data():
if Path(Config["Path"]["Save"]).is_file(): if Path(Config["Path"]["Save"]).is_file():
Config["Path"]["Save"] = str(Path(Config["Path"]["Save"]).parent) 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: if result.status:
Config["Path"]["Input_BCG"] = result.data["path"] Config["Path"]["Input_BCG"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"] Config["InputConfig"]["ThoFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_Artifact"] = result.data["path"] Config["Path"]["Input_Artifact"] = result.data["path"]
else: else:
@ -976,19 +977,19 @@ class Data():
if Config["Mode"] == "30s": if Config["Mode"] == "30s":
Config["Path"]["Save"] = str( 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": elif Config["Mode"] == "10s":
Config["Path"]["Save"] = str( 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: else:
raise ValueError("模式不存在") raise ValueError("模式不存在")
try: try:
self.BCG = read_csv(Config["Path"]["Input_BCG"], self.BCG = read_csv(Config["Path"]["Input_BCG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Artifact_a = read_csv(Config["Path"]["Input_Artifact"], self.Artifact_a = read_csv(Config["Path"]["Input_Artifact"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc()) 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): def get_archive(self):
if Config["Mode"] == "30s": if Config["Mode"] == "30s":
filename = ConfigParams.SQ_LABEL_30S filename = Filename.SQ_LABEL_30S
elif Config["Mode"] == "10s": elif Config["Mode"] == "10s":
filename = ConfigParams.SQ_LABEL_10S filename = Filename.SQ_LABEL_10S
else: else:
raise ValueError("模式不存在") raise ValueError("模式不存在")
@ -1050,7 +1051,7 @@ class Data():
return Result().success(info=filename + "" + Constants.ARCHIVE_NOT_EXIST) return Result().success(info=filename + "" + Constants.ARCHIVE_NOT_EXIST)
else: else:
self.df_label = read_csv(Config["Path"]["Save"], 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) self.label = self.df_label[Constants.BCG_QUALITY_LABEL_COLUMN_LABEL].astype(str)
return Result().success(info=filename + "" + Constants.ARCHIVE_EXIST) 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) Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
if self.df_label is None: 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": if Config["Mode"] == "30s":
filename = ConfigParams.SQ_LABEL_30S filename = Filename.SQ_LABEL_30S
elif Config["Mode"] == "10s": elif Config["Mode"] == "10s":
filename = ConfigParams.SQ_LABEL_10S filename = Filename.SQ_LABEL_10S
else: else:
raise ValueError("模式不存在") raise ValueError("模式不存在")
try: 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: except Exception as e:
return Result().failure(info=filename + Constants.SAVE_FAILURE + return Result().failure(info=filename + Constants.SAVE_FAILURE +
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc()) Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
return Result().success(info=filename + Constants.SAVE_FINISHED + "标签为:" + str(label)) return Result().success(info=filename + Constants.SAVE_FINISHED + "标签为:" + str(label))
@staticmethod @staticmethod
def wipe_industrialFrequencyNoise(data, fs): def wipe_industrialFrequencyNoise(data, fs):
# 设计带阻滤波器Notch Filter来滤除49-51Hz的噪声 # 设计带阻滤波器Notch Filter来滤除49-51Hz的噪声

View File

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

View File

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

View File

@ -11,8 +11,9 @@ from overrides import overrides
from pandas import read_csv, DataFrame from pandas import read_csv, DataFrame
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc 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.Result import Result
from func.utils.detect_Rpeak import preprocess, Rpeak_Detection, get_method 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) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH).exists(): if not Path(Params.DETECT_RPEAK_CONFIG_FILE_PATH).exists():
with open(ConfigParams.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f: with open(Params.DETECT_RPEAK_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.DETECT_RPEAK_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
Config.update({ Config.update({
"Path": { "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)))), 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)))) Path(str(self.sampID))))
} }
}) })
@ -91,7 +92,7 @@ class SettingWindow(QMainWindow):
# 保存配置到文件 # 保存配置到文件
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value() 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) dump(self.config, f)
self.close() self.close()
@ -102,18 +103,18 @@ class SettingWindow(QMainWindow):
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input.setPlainText( self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ECG_FILTER + Path(Filename.ECG_FILTER +
str(self.ui.spinBox_input_freq.value()) + str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText( self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.RPEAK_FINAL + Path(Filename.RPEAK_FINAL +
str(self.ui.spinBox_input_freq.value()) + str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
class MainWindow_detect_Rpeak(QMainWindow): 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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) 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.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0) self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0)
self.ax1.grid(True) self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState) PublicFunc.__resetAllButton__(self, ButtonState)
@ -351,7 +352,7 @@ class MainWindow_detect_Rpeak(QMainWindow):
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0) PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
total_rows = len(DataFrame(self.data.peak.reshape(-1))) 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: with open(Config["Path"]["Save"], 'w') as f:
for start in range(0, total_rows, chunk_size): for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows) end = min(start + chunk_size, total_rows)
@ -376,10 +377,10 @@ class MainWindow_detect_Rpeak(QMainWindow):
self.ax0.clear() self.ax0.clear()
self.ax1.clear() self.ax1.clear()
self.ax0.grid(True) 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.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1.grid(True) 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): def update_ui_comboBox_method(self, method_list):
self.ui.comboBox_method.clear() self.ui.comboBox_method.clear()
@ -399,18 +400,18 @@ class Data:
if Path(Config["Path"]["Input"]).is_file(): if Path(Config["Path"]["Input"]).is_file():
Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent) 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: if result.status:
Config["Path"]["Input"] = result.data["path"] Config["Path"]["Input"] = result.data["path"]
Config["InputConfig"]["Freq"] = result.data["freq"] Config["InputConfig"]["Freq"] = result.data["freq"]
Config["Path"]["Save"] = str( 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: else:
return result return result
try: try:
self.raw_data = read_csv(Config["Path"]["Input"], self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + 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 scipy.signal import find_peaks
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc 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.Filters.Preprocessing import data_preprocess_for_label_check
from func.utils.Result import Result from func.utils.Result import Result
@ -69,11 +70,11 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH).exists(): if not Path(Params.LABEL_CHECK_CONFIG_FILE_PATH).exists():
with open(ConfigParams.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f: with open(Params.LABEL_CHECK_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.LABEL_CHECK_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
@ -81,13 +82,13 @@ class SettingWindow(QMainWindow):
if self.mode == "BCG": if self.mode == "BCG":
Config.update({ Config.update({
"Path": { "Path": {
"Input_Signal": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / "Input_Signal": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))), Path(str(self.sampID)))),
"Input_Peak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / "Input_Peak": str((Path(self.root_path) / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)))), 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)))), 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)))) Path(str(self.sampID))))
}, },
"Mode": self.mode "Mode": self.mode
@ -95,13 +96,13 @@ class SettingWindow(QMainWindow):
elif self.mode == "ECG": elif self.mode == "ECG":
Config.update({ Config.update({
"Path": { "Path": {
"Input_Signal": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT / "Input_Signal": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))), Path(str(self.sampID)))),
"Input_Peak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT / "Input_Peak": str((Path(self.root_path) / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)))), 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)))), 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)))) Path(str(self.sampID))))
}, },
"Mode": self.mode "Mode": self.mode
@ -147,7 +148,7 @@ class SettingWindow(QMainWindow):
# 保存配置到文件 # 保存配置到文件
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq_signal.value() 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) dump(self.config, f)
self.close() self.close()
@ -159,47 +160,47 @@ class SettingWindow(QMainWindow):
if self.mode == "BCG": if self.mode == "BCG":
self.ui.plainTextEdit_file_path_input_signal.setPlainText( self.ui.plainTextEdit_file_path_input_signal.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.BCG_FILTER + Path(Filename.BCG_FILTER +
str(self.ui.spinBox_input_freq_signal.value()) + str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_peak.setPlainText( self.ui.plainTextEdit_file_path_input_peak.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.JPEAK_REVISE + Path(Filename.JPEAK_REVISE +
str(self.ui.spinBox_input_freq_signal.value()) + str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText( self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.JPEAK_REVISE_CORRECTED + Path(Filename.JPEAK_REVISE_CORRECTED +
str(self.ui.spinBox_input_freq_signal.value()) + str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
elif self.mode == "ECG": elif self.mode == "ECG":
self.ui.plainTextEdit_file_path_input_signal.setPlainText( self.ui.plainTextEdit_file_path_input_signal.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ECG_FILTER + Path(Filename.ECG_FILTER +
str(self.ui.spinBox_input_freq_signal.value()) + str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_peak.setPlainText( self.ui.plainTextEdit_file_path_input_peak.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.RPEAK_FINAL + Path(Filename.RPEAK_FINAL +
str(self.ui.spinBox_input_freq_signal.value()) + str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText( self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.RPEAK_FINAL_CORRECTED + Path(Filename.RPEAK_FINAL_CORRECTED +
str(self.ui.spinBox_input_freq_signal.value()) + str(self.ui.spinBox_input_freq_signal.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
else: else:
raise ValueError("模式不存在") 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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) 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.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 = self.fig.add_subplot(self.gs[1], sharex=self.ax0, sharey=self.ax0)
self.ax1.grid(True) self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState) PublicFunc.__resetAllButton__(self, ButtonState)
@ -638,12 +639,12 @@ class MainWindow_label_check(QMainWindow):
if self.ax0 is not None: if self.ax0 is not None:
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE) self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax1 is not None: if self.ax1 is not None:
self.ax1.clear() self.ax1.clear()
self.ax1.grid(True) 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): def on_xlim_change(self, event_ax):
try: try:
@ -835,11 +836,11 @@ class MainWindow_label_check(QMainWindow):
if self.figToolbar.rect_patch_ax0 is None: if self.figToolbar.rect_patch_ax0 is None:
if self.is_left_button_pressed: if self.is_left_button_pressed:
self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True, self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY, alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK) color=Constants.PLOT_COLOR_PINK)
elif self.is_right_button_pressed: elif self.is_right_button_pressed:
self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True, self.figToolbar.rect_patch_ax0 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY, alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED) color=Constants.PLOT_COLOR_RED)
self.ax0.add_patch(self.figToolbar.rect_patch_ax0) self.ax0.add_patch(self.figToolbar.rect_patch_ax0)
@ -847,11 +848,11 @@ class MainWindow_label_check(QMainWindow):
if self.figToolbar.rect_patch_ax1 is None: if self.figToolbar.rect_patch_ax1 is None:
if self.is_left_button_pressed: if self.is_left_button_pressed:
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True, self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY, alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK) color=Constants.PLOT_COLOR_PINK)
elif self.is_right_button_pressed: elif self.is_right_button_pressed:
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True, self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.LABEL_CHECK_LABEL_TRANSPARENCY, alpha=Params.LABEL_CHECK_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED) color=Constants.PLOT_COLOR_RED)
self.ax1.add_patch(self.figToolbar.rect_patch_ax1) self.ax1.add_patch(self.figToolbar.rect_patch_ax1)
@ -883,13 +884,13 @@ class Data:
def open_file(self): def open_file(self):
if Config["Mode"] == "BCG": if Config["Mode"] == "BCG":
signal = ConfigParams.BCG_FILTER signal = Filename.BCG_FILTER
peak = ConfigParams.JPEAK_REVISE peak = Filename.JPEAK_REVISE
save = ConfigParams.JPEAK_REVISE_CORRECTED save = Filename.JPEAK_REVISE_CORRECTED
elif Config["Mode"] == "ECG": elif Config["Mode"] == "ECG":
signal = ConfigParams.ECG_FILTER signal = Filename.ECG_FILTER
peak = ConfigParams.RPEAK_FINAL peak = Filename.RPEAK_FINAL
save = ConfigParams.RPEAK_FINAL_CORRECTED save = Filename.RPEAK_FINAL_CORRECTED
else: else:
raise ValueError("模式不存在") raise ValueError("模式不存在")
if Path(Config["Path"]["Input_Signal"]).is_file(): if Path(Config["Path"]["Input_Signal"]).is_file():
@ -901,7 +902,7 @@ class Data:
if Path(Config["Path"]["Save"]).is_file(): if Path(Config["Path"]["Save"]).is_file():
Config["Path"]["Save"] = str(Path(Config["Path"]["Save"]).parent) 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: if result.status:
Config["Path"]["Input_Signal"] = result.data["path"] Config["Path"]["Input_Signal"] = result.data["path"]
Config["InputConfig"]["Freq"] = result.data["freq"] Config["InputConfig"]["Freq"] = result.data["freq"]
@ -909,12 +910,12 @@ class Data:
return result return result
Config["Path"]["Input_Peak"] = str( 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( Config["Path"]["Input_Approximately_Align"] = str(
Path(Config["Path"]["Input_Approximately_Align"]) / Path( 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( 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(): if not Path(Config["Path"]["Input_Peak"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" + return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
@ -923,16 +924,16 @@ class Data:
Constants.FAILURE_REASON["Path_Not_Exist"]) Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Approximately_Align"]).exists(): if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" + return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.APPROXIMATELY_ALIGN_INFO + "" + Filename.APPROXIMATELY_ALIGN_INFO + "" +
Config["Path"]["Input_Approximately_Align"] + Config["Path"]["Input_Approximately_Align"] +
Constants.FAILURE_REASON["Path_Not_Exist"]) Constants.FAILURE_REASON["Path_Not_Exist"])
try: try:
self.raw_data = read_csv(Config["Path"]["Input_Signal"], self.raw_data = read_csv(Config["Path"]["Input_Signal"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.original_peak = read_csv(Config["Path"]["Input_Peak"], self.original_peak = read_csv(Config["Path"]["Input_Peak"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + return Result().failure(info=Constants.INPUT_FAILURE +
@ -967,7 +968,7 @@ class Data:
return Result().success(info=Constants.ARCHIVE_NOT_EXIST) return Result().success(info=Constants.ARCHIVE_NOT_EXIST)
else: else:
self.corrected_peak = read_csv(Config["Path"]["Save"], self.corrected_peak = read_csv(Config["Path"]["Save"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
return Result().success(info=Constants.ARCHIVE_EXIST) return Result().success(info=Constants.ARCHIVE_EXIST)
@ -1017,19 +1018,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
super().__init__(canvas, parent) super().__init__(canvas, parent)
# 初始化画框工具栏 # 初始化画框工具栏
self.action_Label_Multiple = QAction(Constants.LABEL_CHECK_ACTION_LABEL_MULTIPLE_NAME, self) 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.setCheckable(True)
self.action_Label_Multiple.setShortcut(QCoreApplication.translate( self.action_Label_Multiple.setShortcut(QCoreApplication.translate(
"MainWindow", "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.insertAction(self._actions['pan'], self.action_Label_Multiple)
self._actions['pan'].setShortcut(QCoreApplication.translate( self._actions['pan'].setShortcut(QCoreApplication.translate(
"MainWindow", "MainWindow",
ConfigParams.ACTION_PAN_SHORTCUT_KEY)) Params.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate( self._actions['zoom'].setShortcut(QCoreApplication.translate(
"MainWindow", "MainWindow",
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY)) Params.ACTION_ZOOM_SHORTCUT_KEY))
# 用于存储事件连接ID # 用于存储事件连接ID
self.cid_mouse_press = None 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_resp_quality_label import MainWindow_resp_quality_label
from func.Module_SA_label import MainWindow_SA_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") use("QtAgg")
@ -54,7 +55,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.__read_config__() self.__read_config__()
self.ui.plainTextEdit_root_path.setPlainText(Config["Path"]["Root"]) 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.approximately_align = None
self.preprocess = None self.preprocess = None
@ -86,18 +87,18 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
@staticmethod @staticmethod
def __read_config__(): def __read_config__():
if not Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).exists(): if not Path(Params.PUBLIC_CONFIG_FILE_PATH).exists():
Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).parent.mkdir(parents=True, exist_ok=True) Path(Params.PUBLIC_CONFIG_FILE_PATH).parent.mkdir(parents=True, exist_ok=True)
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "w") as f: with open(Params.PUBLIC_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PUBLIC_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
@staticmethod @staticmethod
def __write_config__(): 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) dump(Config, f)
def __slot_btn_open__(self): def __slot_btn_open__(self):
@ -105,7 +106,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
file_dialog.setFileMode(QFileDialog.Directory) file_dialog.setFileMode(QFileDialog.Directory)
file_dialog.setOption(QFileDialog.ShowDirsOnly, True) file_dialog.setOption(QFileDialog.ShowDirsOnly, True)
if file_dialog.exec_() == QFileDialog.Accepted: 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]) 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 scipy.signal import find_peaks
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc 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.Result import Result
from ui.MainWindow.MainWindow_precisely_align import Ui_MainWindow_precisely_align 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) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH).exists(): if not Path(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH).exists():
with open(ConfigParams.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f: with open(Params.PRECISELY_ALIGN_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PRECISELY_ALIGN_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
Config.update({ Config.update({
"Path": { "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)))), 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)))), 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)))), 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)))), 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)))), 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)))), Path(str(self.sampID)))),
"Save_AlignInfo": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL / "Save_AlignInfo": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))), Path(str(self.sampID)))),
"Save_OrgBCG": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / "Save_OrgBCG": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))), 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)))), 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)))), Path(str(self.sampID)))),
"Save_Jpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / "Save_Jpeak": str((Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)))), Path(str(self.sampID)))),
"Save_Rpeak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED / "Save_Rpeak": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))) Path(str(self.sampID))))
}, },
"Coordinate": { "Coordinate": {
@ -221,7 +222,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.value() self.config["InputConfig"]["BCGFreq"] = self.ui.spinBox_input_freq_BCG.value()
self.config["InputConfig"]["ECGFreq"] = self.ui.spinBox_input_freq_ECG.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) dump(self.config, f)
self.close() self.close()
@ -232,60 +233,60 @@ class SettingWindow(QMainWindow):
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText( self.ui.plainTextEdit_file_path_input_orgBcg.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_RAW + Path(Filename.ORGBCG_RAW +
str(self.ui.spinBox_input_freq_orgBcg.value()) + str(self.ui.spinBox_input_freq_orgBcg.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_BCG.setPlainText( self.ui.plainTextEdit_file_path_input_BCG.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.BCG_FILTER + Path(Filename.BCG_FILTER +
str(self.ui.spinBox_input_freq_BCG.value()) + str(self.ui.spinBox_input_freq_BCG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_ECG.setPlainText( self.ui.plainTextEdit_file_path_input_ECG.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ECG_FILTER + Path(Filename.ECG_FILTER +
str(self.ui.spinBox_input_freq_ECG.value()) + str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_orgBcg.setPlainText( self.ui.plainTextEdit_file_path_save_orgBcg.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_SYNC + Path(Filename.ORGBCG_SYNC +
str(self.ui.spinBox_input_freq_orgBcg.value()) + str(self.ui.spinBox_input_freq_orgBcg.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_BCG.setPlainText( self.ui.plainTextEdit_file_path_save_BCG.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.BCG_SYNC + Path(Filename.BCG_SYNC +
str(self.ui.spinBox_input_freq_BCG.value()) + str(self.ui.spinBox_input_freq_BCG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_ECG.setPlainText( self.ui.plainTextEdit_file_path_save_ECG.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ECG_SYNC + Path(Filename.ECG_SYNC +
str(self.ui.spinBox_input_freq_ECG.value()) + str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_Jpeak.setPlainText( self.ui.plainTextEdit_file_path_save_Jpeak.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.JPEAK_SYNC + Path(Filename.JPEAK_SYNC +
str(self.ui.spinBox_input_freq_BCG.value()) + str(self.ui.spinBox_input_freq_BCG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save_Rpeak.setPlainText( self.ui.plainTextEdit_file_path_save_Rpeak.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.RPEAK_SYNC + Path(Filename.RPEAK_SYNC +
str(self.ui.spinBox_input_freq_ECG.value()) + str(self.ui.spinBox_input_freq_ECG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
class MainWindow_precisely_align(QMainWindow): 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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) 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 = self.fig.add_subplot(self.gs[1], sharex=self.ax0, sharey=self.ax0)
self.ax1.grid(True) 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] Jpeak = self.data.Jpeak[:-2]
Rpeak = self.data.Rpeak[:-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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) 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 = self.fig.add_subplot(self.gs[2])
self.ax1.grid(True) 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 = self.fig.add_subplot(self.gs[1])
self.ax2.grid(True) 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 = self.fig.add_subplot(self.gs[3])
self.ax3.grid(True) self.ax3.grid(True)
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.set_title( 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( "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.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 = self.fig.add_subplot(self.gs[0])
self.ax4.grid(True) 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.set_title("offset correct")
self.ax4.plot(plot_element["cut_ECG"], color=Constants.PLOT_COLOR_GREEN, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_ECG) 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.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 = self.fig.add_subplot(self.gs[0])
self.ax4.grid(True) 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.set_title("result preview")
self.ax4.plot(self.data.cut_ECG, color=Constants.PLOT_COLOR_GREEN, label=Constants.PRECISELY_ALIGN_PLOT_LABEL_ECG) 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) PublicFunc.progressbar_update(self, 2, 6, Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG, 0)
total_rows = len(DataFrame(self.data.res_orgBcg.reshape(-1))) 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: with open(Config["Path"]["Save_OrgBCG"], 'w') as f:
for start in range(0, total_rows, chunk_size): for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows) 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) PublicFunc.progressbar_update(self, 3, 6, Constants.PRECISELY_ALIGN_SAVING_RES_BCG, 0)
total_rows = len(DataFrame(self.data.res_BCG.reshape(-1))) 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: with open(Config["Path"]["Save_BCG"], 'w') as f:
for start in range(0, total_rows, chunk_size): for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows) 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) PublicFunc.progressbar_update(self, 4, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_ECG, 0)
total_rows = len(DataFrame(self.data.cut_ECG.reshape(-1))) 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: with open(Config["Path"]["Save_ECG"], 'w') as f:
for start in range(0, total_rows, chunk_size): for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows) 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) PublicFunc.progressbar_update(self, 5, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_JPEAK, 0)
total_rows = len(DataFrame(self.data.cut_Jpeak.reshape(-1))) 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: with open(Config["Path"]["Save_Jpeak"], 'w') as f:
for start in range(0, total_rows, chunk_size): for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows) 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) PublicFunc.progressbar_update(self, 6, 6, Constants.PRECISELY_ALIGN_SAVING_CUT_RPEAK, 0)
total_rows = len(DataFrame(self.data.cut_Rpeak.reshape(-1))) 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: with open(Config["Path"]["Save_Rpeak"], 'w') as f:
for start in range(0, total_rows, chunk_size): for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows) end = min(start + chunk_size, total_rows)
@ -1014,23 +1015,23 @@ class MainWindow_precisely_align(QMainWindow):
if self.ax0 is not None: if self.ax0 is not None:
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
if self.ax1 is not None: if self.ax1 is not None:
self.ax1.clear() self.ax1.clear()
self.ax1.grid(True) 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: if self.ax2 is not None:
self.ax2.clear() self.ax2.clear()
self.ax2.grid(True) 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: if self.ax3 is not None:
self.ax3.clear() self.ax3.clear()
self.ax3.grid(True) 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: if self.ax4 is not None:
self.ax4.clear() self.ax4.clear()
self.ax4.grid(True) 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): def redraw_calculate_coordination(self, plot_element=None):
if plot_element is not None and plot_element["mode"] == "select": if plot_element is not None and plot_element["mode"] == "select":
@ -1327,25 +1328,25 @@ class MainWindow_precisely_align(QMainWindow):
if self.figToolbar.ax0_BCG_rectangle_front is None and self.is_left_button_pressed: 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, self.figToolbar.ax0_BCG_rectangle_front = patches.Rectangle((0, 0), 1, 1,
fill=True, fill=True,
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY, alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK) color=Constants.PLOT_COLOR_PINK)
self.ax0.add_patch(self.figToolbar.ax0_BCG_rectangle_front) 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: 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, self.figToolbar.ax0_BCG_rectangle_back = patches.Rectangle((0, 0), 1, 1,
fill=True, fill=True,
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY, alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK) color=Constants.PLOT_COLOR_PINK)
self.ax0.add_patch(self.figToolbar.ax0_BCG_rectangle_back) 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: 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, self.figToolbar.ax1_ECG_rectangle_front = patches.Rectangle((0, 0), 1, 1,
fill=True, fill=True,
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY, alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK) color=Constants.PLOT_COLOR_PINK)
self.ax1.add_patch(self.figToolbar.ax1_ECG_rectangle_front) 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: 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, self.figToolbar.ax1_ECG_rectangle_back = patches.Rectangle((0, 0), 1, 1,
fill=True, fill=True,
alpha=ConfigParams.PRECISELY_ALIGN_LABEL_TRANSPARENCY, alpha=Params.PRECISELY_ALIGN_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK) color=Constants.PLOT_COLOR_PINK)
self.ax1.add_patch(self.figToolbar.ax1_ECG_rectangle_back) self.ax1.add_patch(self.figToolbar.ax1_ECG_rectangle_back)
@ -1454,7 +1455,7 @@ class Data:
if Path(Config["Path"]["Input_Approximately_Align"]).is_file(): if Path(Config["Path"]["Input_Approximately_Align"]).is_file():
Config["Path"]["Input_Approximately_Align"] = str(Path(Config["Path"]["Input_Approximately_Align"]).parent) 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: if result.status:
Config["Path"]["Input_OrgBCG"] = result.data["path"] Config["Path"]["Input_OrgBCG"] = result.data["path"]
Config["InputConfig"]["orgBcgFreq"] = result.data["freq"] Config["InputConfig"]["orgBcgFreq"] = result.data["freq"]
@ -1462,29 +1463,29 @@ class Data:
return result return result
Config["Path"]["Input_Approximately_Align"] = str( Config["Path"]["Input_Approximately_Align"] = str(
Path(Config["Path"]["Input_Approximately_Align"]) / Path( 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( Config["Path"]["Save_AlignInfo"] = str(
Path(Config["Path"]["Save_AlignInfo"]) / Path( 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( Config["Path"]["Save_OrgBCG"] = str(
Path(Config["Path"]["Save_OrgBCG"]) / Path( Path(Config["Path"]["Save_OrgBCG"]) / Path(
ConfigParams.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + ConfigParams.ENDSWITH_TXT)) Filename.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + Params.ENDSWITH_TXT))
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], ConfigParams.BCG_FILTER, ConfigParams.ENDSWITH_TXT) result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_FILTER, Params.ENDSWITH_TXT)
if result.status: if result.status:
Config["Path"]["Input_BCG"] = result.data["path"] Config["Path"]["Input_BCG"] = result.data["path"]
Config["InputConfig"]["BCGFreq"] = result.data["freq"] Config["InputConfig"]["BCGFreq"] = result.data["freq"]
else: else:
return result return result
Config["Path"]["Input_Jpeak"] = str( Config["Path"]["Input_Jpeak"] = str(
Path(Config["Path"]["Input_Jpeak"]) / Path(ConfigParams.JPEAK_REVISE_CORRECTED + str( Path(Config["Path"]["Input_Jpeak"]) / Path(Filename.JPEAK_REVISE_CORRECTED + str(
Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT)) Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_BCG"] = str( Config["Path"]["Save_BCG"] = str(
Path(Config["Path"]["Save_BCG"]) / Path( 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( Config["Path"]["Save_Jpeak"] = str(
Path(Config["Path"]["Save_Jpeak"]) / Path( Path(Config["Path"]["Save_Jpeak"]) / Path(
ConfigParams.JPEAK_SYNC + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT)) Filename.JPEAK_SYNC + str(Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], ConfigParams.ECG_FILTER, ConfigParams.ENDSWITH_TXT) result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], Filename.ECG_FILTER, Params.ENDSWITH_TXT)
if result.status: if result.status:
Config["Path"]["Input_ECG"] = result.data["path"] Config["Path"]["Input_ECG"] = result.data["path"]
Config["InputConfig"]["ECGFreq"] = result.data["freq"] Config["InputConfig"]["ECGFreq"] = result.data["freq"]
@ -1492,45 +1493,45 @@ class Data:
return result return result
Config["Path"]["Input_Rpeak"] = str( Config["Path"]["Input_Rpeak"] = str(
Path(Config["Path"]["Input_Rpeak"]) / Path( 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( Config["Path"]["Save_ECG"] = str(
Path(Config["Path"]["Save_ECG"]) / Path( 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( Config["Path"]["Save_Rpeak"] = str(
Path(Config["Path"]["Save_Rpeak"]) / Path( 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(): if not Path(Config["Path"]["Input_Jpeak"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" + return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.JPEAK_REVISE_CORRECTED + "" + Filename.JPEAK_REVISE_CORRECTED + "" +
Config["Path"]["Input_Jpeak"] + Config["Path"]["Input_Jpeak"] +
Constants.FAILURE_REASON["Path_Not_Exist"]) Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Rpeak"]).exists(): if not Path(Config["Path"]["Input_Rpeak"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" + return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.RPEAK_FINAL_CORRECTED + "" + Filename.RPEAK_FINAL_CORRECTED + "" +
Config["Path"]["Input_Rpeak"] + Config["Path"]["Input_Rpeak"] +
Constants.FAILURE_REASON["Path_Not_Exist"]) Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Approximately_Align"]).exists(): if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" + return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
ConfigParams.APPROXIMATELY_ALIGN_INFO + "" + Filename.APPROXIMATELY_ALIGN_INFO + "" +
Config["Path"]["Input_Approximately_Align"] + Config["Path"]["Input_Approximately_Align"] +
Constants.FAILURE_REASON["Path_Not_Exist"]) Constants.FAILURE_REASON["Path_Not_Exist"])
try: try:
self.raw_orgBcg = read_csv(Config["Path"]["Input_OrgBCG"], self.raw_orgBcg = read_csv(Config["Path"]["Input_OrgBCG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.raw_BCG = read_csv(Config["Path"]["Input_BCG"], self.raw_BCG = read_csv(Config["Path"]["Input_BCG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Jpeak = read_csv(Config["Path"]["Input_Jpeak"], self.Jpeak = read_csv(Config["Path"]["Input_Jpeak"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.raw_ECG = read_csv(Config["Path"]["Input_ECG"], self.raw_ECG = read_csv(Config["Path"]["Input_ECG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Rpeak = read_csv(Config["Path"]["Input_Rpeak"], self.Rpeak = read_csv(Config["Path"]["Input_Rpeak"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.argmax_BCG = np_argmax(self.raw_BCG) self.argmax_BCG = np_argmax(self.raw_BCG)
self.argmax_ECG = np_argmax(self.raw_ECG) self.argmax_ECG = np_argmax(self.raw_ECG)
@ -2004,19 +2005,19 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
super().__init__(canvas, parent) super().__init__(canvas, parent)
# 初始化画框工具栏 # 初始化画框工具栏
self.action_Get_Range = QAction(Constants.PRECISELY_ALIGN_ACTION_GET_RANGE_NAME, self) 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.setCheckable(True)
self.action_Get_Range.setShortcut(QCoreApplication.translate( self.action_Get_Range.setShortcut(QCoreApplication.translate(
"MainWindow", "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.insertAction(self._actions['pan'], self.action_Get_Range)
self._actions['pan'].setShortcut(QCoreApplication.translate( self._actions['pan'].setShortcut(QCoreApplication.translate(
"MainWindow", "MainWindow",
ConfigParams.ACTION_PAN_SHORTCUT_KEY)) Params.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate( self._actions['zoom'].setShortcut(QCoreApplication.translate(
"MainWindow", "MainWindow",
ConfigParams.ACTION_ZOOM_SHORTCUT_KEY)) Params.ACTION_ZOOM_SHORTCUT_KEY))
# 用于存储事件连接ID # 用于存储事件连接ID
self.cid_mouse_press = None self.cid_mouse_press = None

View File

@ -12,8 +12,9 @@ from pandas import read_csv, DataFrame
from scipy.signal import resample from scipy.signal import resample
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc 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.Filters.Preprocessing import Butterworth_for_BCG_PreProcess, Butterworth_for_ECG_PreProcess
from func.utils.Result import Result from func.utils.Result import Result
@ -62,11 +63,11 @@ class SettingWindow(QMainWindow):
self.ui.pushButton_cancel.clicked.connect(self.close) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.PREPROCESS_CONFIG_FILE_PATH).exists(): if not Path(Params.PREPROCESS_CONFIG_FILE_PATH).exists():
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f: with open(Params.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
dump(ConfigParams.PREPROCESS_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
@ -74,9 +75,9 @@ class SettingWindow(QMainWindow):
if self.mode == "BCG": if self.mode == "BCG":
Config.update({ Config.update({
"Path": { "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)))), 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)))) Path(str(self.sampID))))
}, },
"Mode": self.mode "Mode": self.mode
@ -84,9 +85,9 @@ class SettingWindow(QMainWindow):
elif self.mode == "ECG": elif self.mode == "ECG":
Config.update({ Config.update({
"Path": { "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)))), 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)))) Path(str(self.sampID))))
}, },
"Mode": self.mode "Mode": self.mode
@ -111,7 +112,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value() self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
self.config["OutputConfig"]["Freq"] = self.ui.spinBox_output_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) dump(self.config, f)
self.close() self.close()
@ -123,33 +124,33 @@ class SettingWindow(QMainWindow):
if self.mode == "BCG": if self.mode == "BCG":
self.ui.plainTextEdit_file_path_input.setPlainText( self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_RAW + Path(Filename.ORGBCG_RAW +
str(self.ui.spinBox_input_freq.value()) + str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText( self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT / Filename.PATH_ORGBCG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.BCG_FILTER + Path(Filename.BCG_FILTER +
str(self.ui.spinBox_output_freq.value()) + str(self.ui.spinBox_output_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
elif self.mode == "ECG": elif self.mode == "ECG":
self.ui.plainTextEdit_file_path_input.setPlainText( self.ui.plainTextEdit_file_path_input.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ECG_RAW + Path(Filename.ECG_RAW +
str(self.ui.spinBox_input_freq.value()) + str(self.ui.spinBox_input_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_save.setPlainText( self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_TEXT / Filename.PATH_PSG_TEXT /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ECG_FILTER + Path(Filename.ECG_FILTER +
str(self.ui.spinBox_output_freq.value()) + str(self.ui.spinBox_output_freq.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
else: else:
raise ValueError("模式不存在") 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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
PublicFunc.__resetAllButton__(self, ButtonState) PublicFunc.__resetAllButton__(self, ButtonState)
@ -364,7 +365,7 @@ class MainWindow_preprocess(QMainWindow):
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0) PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
total_rows = len(DataFrame(self.data.processed_data.reshape(-1))) 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: with open(Config["Path"]["Save"], 'w') as f:
for start in range(0, total_rows, chunk_size): for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows) end = min(start + chunk_size, total_rows)
@ -389,7 +390,7 @@ class MainWindow_preprocess(QMainWindow):
if self.ax0 is not None: if self.ax0 is not None:
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
class Data: class Data:
@ -400,28 +401,28 @@ class Data:
def open_file(self): def open_file(self):
if Config["Mode"] == "BCG": if Config["Mode"] == "BCG":
signal = ConfigParams.ORGBCG_RAW signal = Filename.ORGBCG_RAW
save = ConfigParams.BCG_FILTER save = Filename.BCG_FILTER
elif Config["Mode"] == "ECG": elif Config["Mode"] == "ECG":
signal = ConfigParams.ECG_RAW signal = Filename.ECG_RAW
save = ConfigParams.ECG_FILTER save = Filename.ECG_FILTER
else: else:
raise ValueError("模式不存在") raise ValueError("模式不存在")
if Path(Config["Path"]["Input"]).is_file(): if Path(Config["Path"]["Input"]).is_file():
Config["Path"]["Input"] = str(Path(Config["Path"]["Input"]).parent) 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: if result.status:
Config["Path"]["Input"] = result.data["path"] Config["Path"]["Input"] = result.data["path"]
Config["InputConfig"]["Freq"] = result.data["freq"] Config["InputConfig"]["Freq"] = result.data["freq"]
Config["Path"]["Save"] = str( 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: else:
return result return result
try: try:
self.raw_data = read_csv(Config["Path"]["Input"], self.raw_data = read_csv(Config["Path"]["Input"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + 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 scipy.signal import find_peaks, resample
from yaml import dump, load, FullLoader from yaml import dump, load, FullLoader
from func.utils.ConfigParams import Filename, Params
from func.utils.PublicFunc import PublicFunc 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 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 import pre_process, get_slice, evaluate_quality
from func.utils.resp_quality_label_filter import get_bandpass_bcgsignal 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) self.ui.pushButton_cancel.clicked.connect(self.close)
def __read_config__(self): def __read_config__(self):
if not Path(ConfigParams.RESP_QUALITY_LABEL_CONFIG_FILE_PATH).exists(): if not Path(Params.RESP_QUALITY_LABEL_CONFIG_FILE_PATH).exists():
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(ConfigParams.RESP_QUALITY_LABEL_CONFIG_NEW_CONTENT, 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) file_config = load(f.read(), Loader=FullLoader)
Config.update(file_config) Config.update(file_config)
self.config = file_config self.config = file_config
Config.update({ Config.update({
"Path": { "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)))), 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)))), 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)))), Path(str(self.sampID)))),
"Save_Resp_quality_label": 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)))), Path(str(self.sampID)))),
"Save_Tho_peak": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL / "Save_Tho_peak": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))) Path(str(self.sampID))))
}, },
"CurrentPartNum": 1, "CurrentPartNum": 1,
@ -133,7 +133,7 @@ class SettingWindow(QMainWindow):
self.config["InputConfig"]["OrgBCGFreq"] = self.ui.spinBox_input_freq_signal_OrgBCG.value() self.config["InputConfig"]["OrgBCGFreq"] = self.ui.spinBox_input_freq_signal_OrgBCG.value()
self.config["InputConfig"]["ThoFreq"] = self.ui.spinBox_input_freq_signal_Tho.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) dump(self.config, f)
self.close() self.close()
@ -144,18 +144,18 @@ class SettingWindow(QMainWindow):
def __update_ui__(self): def __update_ui__(self):
self.ui.plainTextEdit_file_path_input_signal_OrgBCG.setPlainText( self.ui.plainTextEdit_file_path_input_signal_OrgBCG.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_ALIGNED / Filename.PATH_ORGBCG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.ORGBCG_SYNC + Path(Filename.ORGBCG_SYNC +
str(self.ui.spinBox_input_freq_signal_OrgBCG.value()) + str(self.ui.spinBox_input_freq_signal_OrgBCG.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
self.ui.plainTextEdit_file_path_input_signal_Tho.setPlainText( self.ui.plainTextEdit_file_path_input_signal_Tho.setPlainText(
str((Path(self.root_path) / str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_PSG_ALIGNED / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)) / Path(str(self.sampID)) /
Path(ConfigParams.THO_SYNC + Path(Filename.THO_SYNC +
str(self.ui.spinBox_input_freq_signal_Tho.value()) + str(self.ui.spinBox_input_freq_signal_Tho.value()) +
ConfigParams.ENDSWITH_TXT)))) Params.ENDSWITH_TXT))))
class MainWindow_resp_quality_label(QMainWindow): 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.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 = self.fig.add_subplot(self.gs[0])
self.ax0.grid(True) 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 = self.fig.add_subplot(self.gs[1])
self.ax1.grid(True) 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) self.fig_spectrum = plt.figure(figsize=(12, 9), dpi=100)
@ -353,10 +353,10 @@ class MainWindow_resp_quality_label(QMainWindow):
try: try:
if Config["CurrentPartNum"] != Config["DataPartNum"]: if Config["CurrentPartNum"] != Config["DataPartNum"]:
begin_OrgBCG = Config["CurrentOrgBCGIndex"] 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"])) int(Config["InputConfig"]["OrgBCGUseFreq"]))
begin_Tho = Config["CurrentThoIndex"] 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"])) int(Config["InputConfig"]["ThoUseFreq"]))
else: else:
begin_OrgBCG = Config["CurrentOrgBCGIndex"] begin_OrgBCG = Config["CurrentOrgBCGIndex"]
@ -428,7 +428,7 @@ class MainWindow_resp_quality_label(QMainWindow):
try: try:
if Config["CurrentPartNum"] != Config["DataPartNum"]: if Config["CurrentPartNum"] != Config["DataPartNum"]:
begin_Tho = Config["CurrentThoIndex"] 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"])) int(Config["InputConfig"]["ThoUseFreq"]))
elif Config["CurrentPartNum"] == Config["DataPartNum"]: elif Config["CurrentPartNum"] == Config["DataPartNum"]:
begin_Tho = Config["CurrentThoIndex"] begin_Tho = Config["CurrentThoIndex"]
@ -730,8 +730,8 @@ class MainWindow_resp_quality_label(QMainWindow):
artifact_indices = [] artifact_indices = []
for i in range(0, len(self.data.Artifact_a)): for i in range(0, len(self.data.Artifact_a)):
if i + 3 < 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 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"] * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC) # 第四行(索引+3 index1 = self.data.Artifact_a[i + 3] // (Config["InputConfig"]["OrgBCGUseFreq"] * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC) # 第四行(索引+3
if index0 == index1: if index0 == index1:
artifact_indices.append(index0) artifact_indices.append(index0)
else: else:
@ -742,10 +742,10 @@ class MainWindow_resp_quality_label(QMainWindow):
# 数据切片预处理 # 数据切片预处理
BCG = pre_process( BCG = pre_process(
get_slice( 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( THO = pre_process(
get_slice( 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 # 有体动1 无体动0
@ -805,9 +805,9 @@ class MainWindow_resp_quality_label(QMainWindow):
PublicFunc.msgbox_output(self, Constants.RESP_QUALITY_LABEL_VIEWING_THE_FIRST_PART, Constants.MSGBOX_TYPE_INFO) PublicFunc.msgbox_output(self, Constants.RESP_QUALITY_LABEL_VIEWING_THE_FIRST_PART, Constants.MSGBOX_TYPE_INFO)
return return
Config["CurrentPartNum"] = Config["CurrentPartNum"] - 1 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"])) int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC * Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"])) int(Config["InputConfig"]["ThoUseFreq"]))
result = self.__plot__() result = self.__plot__()
if not result.status: if not result.status:
@ -836,9 +836,9 @@ class MainWindow_resp_quality_label(QMainWindow):
PublicFunc.msgbox_output(self, Constants.RESP_QUALITY_LABEL_VIEWING_THE_LAST_PART, Constants.MSGBOX_TYPE_INFO) PublicFunc.msgbox_output(self, Constants.RESP_QUALITY_LABEL_VIEWING_THE_LAST_PART, Constants.MSGBOX_TYPE_INFO)
return return
Config["CurrentPartNum"] = Config["CurrentPartNum"] + 1 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"])) int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC * Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"])) int(Config["InputConfig"]["ThoUseFreq"]))
result = self.__plot__() result = self.__plot__()
if not result.status: if not result.status:
@ -870,16 +870,16 @@ class MainWindow_resp_quality_label(QMainWindow):
if sender == self.ui.tableWidget_labeled: if sender == self.ui.tableWidget_labeled:
Config["CurrentPartNum"] = int( Config["CurrentPartNum"] = int(
self.ui.tableWidget_labeled.item(row, 0).text()) self.ui.tableWidget_labeled.item(row, 0).text())
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"])) int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC * Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"])) int(Config["InputConfig"]["ThoUseFreq"]))
elif sender == self.ui.tableWidget_tobelabeled: elif sender == self.ui.tableWidget_tobelabeled:
Config["CurrentPartNum"] = int( Config["CurrentPartNum"] = int(
self.ui.tableWidget_tobelabeled.item(row, 0).text()) self.ui.tableWidget_tobelabeled.item(row, 0).text())
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"])) int(Config["InputConfig"]["OrgBCGUseFreq"]))
Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC * Config["CurrentThoIndex"] = ((Config["CurrentPartNum"] - 1) * Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"])) int(Config["InputConfig"]["ThoUseFreq"]))
else: else:
raise ValueError("发射信号不存在") raise ValueError("发射信号不存在")
@ -956,11 +956,11 @@ class MainWindow_resp_quality_label(QMainWindow):
if self.ax0 is not None: if self.ax0 is not None:
self.ax0.clear() self.ax0.clear()
self.ax0.grid(True) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
if self.ax1 is not None: if self.ax1 is not None:
self.ax1.clear() self.ax1.clear()
self.ax1.grid(True) 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: if self.ax0_spectrum is not None:
self.ax0_spectrum.clear() self.ax0_spectrum.clear()
self.ax0_spectrum.grid(True) self.ax0_spectrum.grid(True)
@ -1093,13 +1093,13 @@ class MainWindow_resp_quality_label(QMainWindow):
self.is_left_button_pressed = False self.is_left_button_pressed = False
if rect_left < Config["CurrentThoIndex"]: if rect_left < Config["CurrentThoIndex"]:
rect_left = Config["CurrentThoIndex"] rect_left = Config["CurrentThoIndex"]
elif rect_left >= (Config["CurrentThoIndex"] + ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC * elif rect_left >= (Config["CurrentThoIndex"] + Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
int(Config["InputConfig"]["ThoUseFreq"])): int(Config["InputConfig"]["ThoUseFreq"])):
rect_left = 0 rect_left = 0
rect_right = 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"])): 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) int(Config["InputConfig"]["ThoUseFreq"]) - 1)
elif rect_right < Config["CurrentThoIndex"]: elif rect_right < Config["CurrentThoIndex"]:
rect_left = 0 rect_left = 0
@ -1167,11 +1167,11 @@ class MainWindow_resp_quality_label(QMainWindow):
if self.figToolbar.rect_patch_ax1 is None: if self.figToolbar.rect_patch_ax1 is None:
if self.is_left_button_pressed: if self.is_left_button_pressed:
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True, self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.RESP_QUALITY_LABEL_LABEL_TRANSPARENCY, alpha=Params.RESP_QUALITY_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_PINK) color=Constants.PLOT_COLOR_PINK)
elif self.is_right_button_pressed: elif self.is_right_button_pressed:
self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True, self.figToolbar.rect_patch_ax1 = patches.Rectangle((0, 0), 1, 1, fill=True,
alpha=ConfigParams.RESP_QUALITY_LABEL_LABEL_TRANSPARENCY, alpha=Params.RESP_QUALITY_LABEL_LABEL_TRANSPARENCY,
color=Constants.PLOT_COLOR_RED) color=Constants.PLOT_COLOR_RED)
self.ax1.add_patch(self.figToolbar.rect_patch_ax1) self.ax1.add_patch(self.figToolbar.rect_patch_ax1)
@ -1215,7 +1215,7 @@ class Data():
if Path(Config["Path"]["Save_Tho_peak"]).is_file(): if Path(Config["Path"]["Save_Tho_peak"]).is_file():
Config["Path"]["Save_Tho_peak"] = str(Path(Config["Path"]["Save_Tho_peak"]).parent) 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: if result.status:
Config["Path"]["Input_Tho"] = result.data["path"] Config["Path"]["Input_Tho"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"] Config["InputConfig"]["ThoFreq"] = result.data["freq"]
@ -1223,11 +1223,11 @@ class Data():
return result return result
Config["Path"]["Save_Tho_peak"] = str( 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: try:
self.Tho = read_csv(Config["Path"]["Input_Tho"], self.Tho = read_csv(Config["Path"]["Input_Tho"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc()) 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"]) return Result().failure(info=Constants.PREPROCESS_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
try: 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: except Exception as e:
return Result().failure(info=Constants.PREPROCESS_FAILURE + return Result().failure(info=Constants.PREPROCESS_FAILURE +
Constants.FAILURE_REASON["Preprocess_Exception"] + "\n" + format_exc()) Constants.FAILURE_REASON["Preprocess_Exception"] + "\n" + format_exc())
@ -1284,15 +1284,15 @@ class Data():
if self.Tho_peak is None: 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: try:
DataFrame(self.Tho_peak).to_csv(Path(Config["Path"]["Save_Tho_peak"]), mode='w', index=False, header=False) DataFrame(self.Tho_peak).to_csv(Path(Config["Path"]["Save_Tho_peak"]), mode='w', index=False, header=False)
except Exception as e: 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()) 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): def open_file_label(self):
if Path(Config["Path"]["Input_OrgBCG"]).is_file(): if Path(Config["Path"]["Input_OrgBCG"]).is_file():
@ -1306,21 +1306,21 @@ class Data():
if Path(Config["Path"]["Save_Tho_peak"]).is_file(): if Path(Config["Path"]["Save_Tho_peak"]).is_file():
Config["Path"]["Save_Tho_peak"] = str(Path(Config["Path"]["Save_Tho_peak"]).parent) 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: if result.status:
Config["Path"]["Input_OrgBCG"] = result.data["path"] Config["Path"]["Input_OrgBCG"] = result.data["path"]
Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"] Config["InputConfig"]["OrgBCGFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_Tho"] = result.data["path"] Config["Path"]["Input_Tho"] = result.data["path"]
Config["InputConfig"]["ThoFreq"] = result.data["freq"] Config["InputConfig"]["ThoFreq"] = result.data["freq"]
else: else:
return result 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: if result.status:
Config["Path"]["Input_Artifact"] = result.data["path"] Config["Path"]["Input_Artifact"] = result.data["path"]
else: else:
@ -1328,26 +1328,26 @@ class Data():
Config["Path"]["Save_Resp_quality_label"] = str( Config["Path"]["Save_Resp_quality_label"] = str(
Path(Config["Path"]["Save_Resp_quality_label"]) / Path( 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( Config["Path"]["Save_Tho_peak"] = str(
Path(Config["Path"]["Save_Tho_peak"]) / Path( 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: try:
self.OrgBCG = read_csv(Config["Path"]["Input_OrgBCG"], self.OrgBCG = read_csv(Config["Path"]["Input_OrgBCG"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Tho = read_csv(Config["Path"]["Input_Tho"], self.Tho = read_csv(Config["Path"]["Input_Tho"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.Artifact_a = read_csv(Config["Path"]["Input_Artifact"], self.Artifact_a = read_csv(Config["Path"]["Input_Artifact"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc()) return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
try: try:
Config["DataPartNum"] = len(self.OrgBCG) // (ConfigParams.RESP_QUALITY_LABEL_PARTS_TIME_SEC * Config["DataPartNum"] = len(self.OrgBCG) // (Params.RESP_QUALITY_LABEL_PARTS_TIME_SEC *
Config["InputConfig"]["OrgBCGFreq"]) + 1 Config["InputConfig"]["OrgBCGFreq"]) + 1
if Config["DataPartNum"] == 0: if Config["DataPartNum"] == 0:
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Data_Length_Not_Correct"]) return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Data_Length_Not_Correct"])
@ -1382,24 +1382,24 @@ class Data():
def get_archive_resp_quality(self): def get_archive_resp_quality(self):
if not Path(Config["Path"]["Save_Resp_quality_label"]).exists(): if not Path(Config["Path"]["Save_Resp_quality_label"]).exists():
self.resp_quality_label = full(Config["DataPartNum"], -1) 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: else:
self.resp_quality_label = read_csv(Config["Path"]["Save_Resp_quality_label"], 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) 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): def get_archive_tho_peak(self):
if not Path(Config["Path"]["Save_Tho_peak"]).exists(): if not Path(Config["Path"]["Save_Tho_peak"]).exists():
self.Tho_peak = array([]).astype(int) self.Tho_peak = array([]).astype(int)
self.Tho_peak_y = 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: else:
self.Tho_peak = read_csv(Config["Path"]["Save_Tho_peak"], self.Tho_peak = read_csv(Config["Path"]["Save_Tho_peak"],
encoding=ConfigParams.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) 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): def resample_tho_and_OrgBCG(self):
if (self.OrgBCG is None) or (self.Tho is None): if (self.OrgBCG is None) or (self.Tho is None):
@ -1431,7 +1431,7 @@ class Data():
try: try:
self.OrgBCG_Processed = self.OrgBCG.copy() 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)] self.Tho_peak_y = [self.Tho_Processed[x] for x in (self.Tho_peak)]
except Exception as e: except Exception as e:
return Result().failure(info=Constants.PREPROCESS_FAILURE + return Result().failure(info=Constants.PREPROCESS_FAILURE +
@ -1441,7 +1441,7 @@ class Data():
def preprocess_getBDR(self, orgBcg_slice, THO_slice, mode): def preprocess_getBDR(self, orgBcg_slice, THO_slice, mode):
orgBcg = pre_process(orgBcg_slice, int(Config["InputConfig"]["OrgBCGUseFreq"]), orgBcg = pre_process(orgBcg_slice, int(Config["InputConfig"]["OrgBCGUseFreq"]),
ConfigParams.RESP_QUALITY_LABEL_PREPROCESS_FC) Params.RESP_QUALITY_LABEL_PREPROCESS_FC)
if mode == "preset": if mode == "preset":
BDR, band_low, band_high, bcg_spectrum, bcg_freq, tho_spectrum, tho_freq = ( BDR, band_low, band_high, bcg_spectrum, bcg_freq, tho_spectrum, tho_freq = (
get_bandpass_bcgsignal(orgBcg, THO_slice, int(Config["InputConfig"]["OrgBCGUseFreq"]), get_bandpass_bcgsignal(orgBcg, THO_slice, int(Config["InputConfig"]["OrgBCGUseFreq"]),
@ -1463,15 +1463,15 @@ class Data():
if self.resp_quality_label is None: 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: try:
DataFrame(self.resp_quality_label).to_csv(Path(Config["Path"]["Save_Resp_quality_label"]), mode='w', index=False, header=False) DataFrame(self.resp_quality_label).to_csv(Path(Config["Path"]["Save_Resp_quality_label"]), mode='w', index=False, header=False)
except Exception as e: 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()) 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): class CustomNavigationToolbar(NavigationToolbar2QT):
@ -1480,14 +1480,14 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
super().__init__(canvas, parent) super().__init__(canvas, parent)
# 初始化画框工具栏 # 初始化画框工具栏
self.action_Label_Multiple = QAction(Constants.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME, self) 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.setCheckable(True)
self.action_Label_Multiple.setShortcut(QCoreApplication.translate("MainWindow", 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.insertAction(self._actions['pan'], self.action_Label_Multiple)
self._actions['pan'].setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.ACTION_PAN_SHORTCUT_KEY)) self._actions['pan'].setShortcut(QCoreApplication.translate("MainWindow", Params.ACTION_PAN_SHORTCUT_KEY))
self._actions['zoom'].setShortcut(QCoreApplication.translate("MainWindow", ConfigParams.ACTION_ZOOM_SHORTCUT_KEY)) self._actions['zoom'].setShortcut(QCoreApplication.translate("MainWindow", Params.ACTION_ZOOM_SHORTCUT_KEY))
# 用于存储事件连接ID # 用于存储事件连接ID
self.cid_mouse_press = None self.cid_mouse_press = None

View File

@ -2,35 +2,20 @@ from PySide6.QtGui import QIntValidator, QDoubleValidator
from matplotlib.ticker import FuncFormatter from matplotlib.ticker import FuncFormatter
class ConfigParams: class Filename:
# 公共
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)
# 文件命名 # 文件命名
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 # Folder: OrgBCG_Text
ORGBCG_RAW: str = "OrgBCG_Raw_" ORGBCG_RAW: str = "OrgBCG_Raw_"
BCG_FILTER: str = "BCG_Filter_" BCG_FILTER: str = "BCG_Filter_"
@ -82,6 +67,28 @@ class ConfigParams:
SQ_LABEL_10S: str = "SQ_label_10s" SQ_LABEL_10S: str = "SQ_label_10s"
SQ_LABEL_30S: str = "SQ_label_30s" 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_FILE_PATH: str = "./config/Config_approximately_align.yaml"
APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT: dict = { APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
@ -207,29 +214,29 @@ class ConfigParams:
CUT_PSG_CONFIG_NEW_CONTENT: dict = { CUT_PSG_CONFIG_NEW_CONTENT: dict = {
"ECGFreq": 1000, "ECGFreq": 1000,
"ChannelInput": { "ChannelInput": {
"Effort Tho": THO_RAW, "Effort Tho": Filename.THO_RAW,
"Effort Abd": ABD_RAW, "Effort Abd": Filename.ABD_RAW,
"Flow T": FLOWT_RAW, "Flow T": Filename.FLOWT_RAW,
"Flow P": FLOWP_RAW, "Flow P": Filename.FLOWP_RAW,
"Snore": SNORE_RAW, "Snore": Filename.SNORE_RAW,
"SpO2": SPO2_RAW, "SpO2": Filename.SPO2_RAW,
"5_class": FIVE_CLASS_RAW "5_class": Filename.FIVE_CLASS_RAW
}, },
"LabelInput": { "LabelInput": {
"SA Label": SA_LABEL_RAW "SA Label": Filename.SA_LABEL_RAW
}, },
"StartTime": STARTTIME_RAW, "StartTime": Filename.STARTTIME_RAW,
"ChannelSave": { "ChannelSave": {
"Effort Tho": THO_SYNC, "Effort Tho": Filename.THO_SYNC,
"Effort Abd": ABD_SYNC, "Effort Abd": Filename.ABD_SYNC,
"Flow T": FLOWT_SYNC, "Flow T": Filename.FLOWT_SYNC,
"Flow P": FLOWP_SYNC, "Flow P": Filename.FLOWP_SYNC,
"Snore": SNORE_SYNC, "Snore": Filename.SNORE_SYNC,
"SpO2": SPO2_SYNC, "SpO2": Filename.SPO2_SYNC,
"5_class": FIVE_CLASS_SYNC "5_class": Filename.FIVE_CLASS_SYNC
}, },
"LabelSave": { "LabelSave": {
"SA Label": SA_LABEL_SYNC "SA Label": Filename.SA_LABEL_SYNC
}, },
"EndWith": { "EndWith": {
"Effort Tho": ENDSWITH_TXT, "Effort Tho": ENDSWITH_TXT,
@ -335,7 +342,6 @@ class ConfigParams:
def __new__(cls): def __new__(cls):
raise TypeError("Constants class cannot be instantiated") raise TypeError("Constants class cannot be instantiated")
# 禁止修改常量 # 禁止修改常量
@classmethod @classmethod
def __setattr__(cls, key, value): 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: class Constants:
@ -240,7 +240,7 @@ class Constants:
LABEL_CHECK_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:" LABEL_CHECK_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
LABEL_CHECK_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:" LABEL_CHECK_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
LABEL_CHECK_NO_POINT_IN_THE_INTERVAL: 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 = "正在处理数据" PRECISELY_ALIGN_PROCESSING_DATA: str = "正在处理数据"
@ -296,7 +296,7 @@ class Constants:
PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT: str = "Selected Point" PRECISELY_ALIGN_PLOT_LABEL_SELECTED_POINT: str = "Selected Point"
PRECISELY_ALIGN_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无有效点" PRECISELY_ALIGN_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无有效点"
PRECISELY_ALIGN_RECOVER_SCALE: 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 = "正在获取文件及其采样率" CUT_PSG_GETTING_FILE_AND_FREQ: str = "正在获取文件及其采样率"
@ -328,7 +328,7 @@ class Constants:
ARTIFACT_LABEL_MERGE: str = "当前所打标的片段距离附近片段不到2秒片段序号" ARTIFACT_LABEL_MERGE: str = "当前所打标的片段距离附近片段不到2秒片段序号"
ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY: str = "体动被删除" ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY: str = "体动被删除"
ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE: 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 = """ ARTIFACT_LABEL_LABELBTN_STYLE_1: str = """
QPushButton { QPushButton {
@ -444,7 +444,7 @@ class Constants:
RESP_QUALITY_LABEL_CUSTOM_FILTER_ARGS_ERROR: str = "OrgBCG带通滤波频率设置范围应为数字范围是0~1" RESP_QUALITY_LABEL_CUSTOM_FILTER_ARGS_ERROR: str = "OrgBCG带通滤波频率设置范围应为数字范围是0~1"
RESP_QUALITY_LABEL_AUTOLABEL_ARGS_ERROR: str = "人工标注阈值设置范围应为数字范围是0~1" RESP_QUALITY_LABEL_AUTOLABEL_ARGS_ERROR: str = "人工标注阈值设置范围应为数字范围是0~1"
RESP_QUALITY_LABEL_CHECK_ARGS_QUESTION_CONTENT: str = "你确定要执行此操作吗,请确保参数输入正确" 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_A_QUALITY: int = 1
RESP_QUALITY_LABEL_B_QUALITY: int = 0 RESP_QUALITY_LABEL_B_QUALITY: int = 0
RESP_QUALITY_LABEL_C_QUALITY: int = -1 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`