Compare commits

...

27 Commits

Author SHA1 Message Date
dd1efc8009 Merge branch 'master' into cxh_dev
# Conflicts:
#	func/Module_approximately_align.py
2025-06-02 20:24:11 +08:00
31a6160c97 修复了<呼吸可用性及间期标注>中绘图失败的问题 2025-05-30 20:46:15 +08:00
e23f3e8ee0 新增了第一次打开<人工纠正>时就保存纠正后的文件的功能 2025-05-29 22:07:37 +08:00
80ffbbcc69 更新README 2025-05-29 21:40:00 +08:00
6494dc8478 新增了<呼吸可用性及间期标注>的体动分类显示的功能 2025-05-29 21:30:25 +08:00
afc93cf498 修复了<BCG的质量标注>中体动显示异常的问题 2025-05-29 21:21:02 +08:00
e379aa6a4a 更新了<BCG的质量标注>和<呼吸可用性及间期标注>的界面 2025-05-29 21:13:44 +08:00
b01e2f1161 修复了路径不存在时无法正确创建文件夹的问题 2025-05-29 14:05:52 +08:00
6b7ba17c6a 完善了<体动标注>中体动选取区域的判别功能 2025-05-29 13:49:44 +08:00
5b7516985f 更新README 2025-05-28 22:07:02 +08:00
13cf749a99 新增脚本filename_regulation_generator.py,有命名规范需要修改时,只需要修改ConfigParams.py的Filename类里面的变量的值,之后直接运行脚本filename_regulation_generator.py即可获取最新版本的数据结构化输入和输出命名规范.html 2025-05-28 22:04:49 +08:00
ee4df5ee93 1、修复了一处文件命名错误
2、添加了一条TODO LIST
2025-05-28 12:59:06 +08:00
29056a96f3 修复了<数据精对齐>中粗对齐虚线位置显示错误的问题 2025-05-27 21:12:55 +08:00
fd184c6384 修复了<呼吸可用性及间期标注>中点击应用并计算进行重新滤波后按钮全部被禁用的问题 2025-05-27 20:34:59 +08:00
wst
976244b3b4 修复了在<数据精对齐>中粗同步结果导入路径错误的问题
修复了在<BCG的J峰算法定位>中模型获取失败时导致的错误
2025-05-23 16:31:05 +08:00
9d88b6ab37 更新TODOLIST 2025-05-23 14:34:48 +08:00
0411966ed0 删除了若干个功能的导出标签按钮,因为其用处不大 2025-05-23 10:42:01 +08:00
6a325ba95b 完成了<BCG的质量标注>的代码重构 2025-05-23 10:25:25 +08:00
54f3852b01 修复了<数据粗同步>的保存路径错误的问题 2025-05-22 21:15:13 +08:00
196ee81a6f 完成了<BCG质量标注>的UI界面 2025-05-22 19:30:28 +08:00
a321dc5bd4 在导入数据时,将校验数据的扩展名是否合法 2025-05-22 17:12:58 +08:00
94b883032d 更改了体动的保存名称 2025-05-22 16:59:52 +08:00
b57bd9e7fa 完成了<呼吸可用性及间期标注>的代码重构
修复了<人工纠正>中多次寻峰时会保存多个相同峰值横坐标的问题
2025-05-22 15:58:29 +08:00
17b896e49d 优化了检查体动标签正确性的代码 2025-05-22 10:50:51 +08:00
c6778b5548 优化了导入数据的代码
更新README
2025-05-22 10:38:47 +08:00
a7758e502e 优化了重置绘图的代码 2025-05-22 10:02:32 +08:00
85a69648e0 优化了重置绘图的代码 2025-05-22 09:50:03 +08:00
31 changed files with 6309 additions and 1437 deletions

View File

@ -9,7 +9,17 @@
## TODO LIST ## TODO LIST
1、根据选定区域获取峰值时将绘制的区域设置为有上限和下限的矩形根据矩形获取到的横纵区域来计算峰值 1、根据选定区域获取峰值时将绘制的区域设置为有上限和下限的矩形根据矩形获取到的横纵区域来计算峰值
2、体动选取区域的判别尚未做的很完整选中多个已有的体动的区域时可能会出现问题 ~~2、体动选取区域的判别尚未做的很完整选中多个已有的体动的区域时可能会出现问题~~
3、部分模块在导入失败后重新导入时会出现问题已知模块有<人工纠正><体动标注><呼吸可用性及间期标注><睡眠呼吸暂停事件标注>,主要是涉及到按钮状态的设置,有待后续优化。当前将这些有涉及到的功能,禁止了导入数据后在不关闭界面的情况下直接重新导入
4、在J峰算法定位的时候滤波导致的信号偏移导致之后的峰值坐标点与实际峰值出现偏移
~~5、写一个脚本用于直接从ConfigParams.py中读取文件命名规则并直接自动化写入到一个markdown文件中。目的是方便文件命名的修改~~
~~6、<呼吸可用性及间期标注>的体动显示做一个和<BCG的质量标注>一样的可以根据勾选来显示需要显示的体动~~
~~7、各个模块中的检测父级文件夹是否存在的功能仍存在问题无法正确创建文件夹~~
## 1、主菜单 ## 1、主菜单

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)))),
"Input_FlowT": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)))), Path(str(self.sampID)))),
"Input_FlowP": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED / "Input_FlowT": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))), Path(str(self.sampID)))),
"Input_SpO2": 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)))),
"Input_Artifact": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL /
Path(str(self.sampID)))),
"Input_Label": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_ALIGNED /
Path(str(self.sampID)))), Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_LABEL / "Input_SpO2": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Input_Artifact": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))),
"Input_Label": str((Path(self.root_path) / Filename.PATH_PSG_ALIGNED /
Path(str(self.sampID)))),
"Save": str((Path(self.root_path) / Filename.PATH_LABEL /
Path(str(self.sampID)))), 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):
@ -609,7 +610,7 @@ class MainWindow_SA_label(QMainWindow):
item = QTableWidgetItem(str(correct_End)) item = QTableWidgetItem(str(correct_End))
self.ui.tableWidget_label_add.setItem(index, 3, item) self.ui.tableWidget_label_add.setItem(index, 3, item)
remark = row.get("remark", None) remark = row.get("remark", None)
if str(remark) != "" and str(remark) != "nan" and row.get("isLabeled", None) == 1: if str(remark) != Constants.STRING_IS_EMPTY and str(remark) != Constants.STRING_IS_NAN and row.get("isLabeled", None) == 1:
for col in range(self.ui.tableWidget_label_add.columnCount()): for col in range(self.ui.tableWidget_label_add.columnCount()):
item = self.ui.tableWidget_label_add.item(index, col) item = self.ui.tableWidget_label_add.item(index, col)
item.setBackground(QColor(255, 200, 200)) item.setBackground(QColor(255, 200, 200))
@ -1000,33 +1001,40 @@ class MainWindow_SA_label(QMainWindow):
self.ui.spinBox_correctEnd.setValue(Config["BCG_EP"]) self.ui.spinBox_correctEnd.setValue(Config["BCG_EP"])
def reset_axes(self): def reset_axes(self):
self.ax0.clear() if self.ax0 is not None:
self.ax1.clear() self.ax0.clear()
self.ax2.clear() self.ax0.grid(True)
self.ax3.clear() self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
self.ax4.clear() self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax5.clear() if self.ax1 is not None:
self.ax6.clear() self.ax1.clear()
self.ax0.grid(True) self.ax1.grid(True)
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
self.ax0.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE) self.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax1.grid(True) if self.ax2 is not None:
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax2.clear()
self.ax1.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE) self.ax2.grid(True)
self.ax2.grid(True) self.ax2.xaxis.set_major_formatter(Params.FORMATTER)
self.ax2.xaxis.set_major_formatter(ConfigParams.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:
self.ax3.grid(True) self.ax3.clear()
self.ax3.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax3.grid(True)
self.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE) self.ax3.xaxis.set_major_formatter(Params.FORMATTER)
self.ax4.grid(True) self.ax3.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax4.xaxis.set_major_formatter(ConfigParams.FORMATTER) if self.ax4 is not None:
self.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE) self.ax4.clear()
self.ax5.grid(True) self.ax4.grid(True)
self.ax5.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax4.xaxis.set_major_formatter(Params.FORMATTER)
self.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE) self.ax4.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
self.ax6.grid(True) if self.ax5 is not None:
self.ax6.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax5.clear()
self.ax5.grid(True)
self.ax5.xaxis.set_major_formatter(Params.FORMATTER)
self.ax5.tick_params(axis='x', colors=Constants.PLOT_COLOR_WHITE)
if self.ax6 is not None:
self.ax6.clear()
self.ax6.grid(True)
self.ax6.xaxis.set_major_formatter(Params.FORMATTER)
def on_xlim_change(self, event_ax): def on_xlim_change(self, event_ax):
# 获取当前x轴范围 # 获取当前x轴范围
@ -1155,7 +1163,7 @@ class MainWindow_SA_label(QMainWindow):
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_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_:
@ -1163,7 +1171,7 @@ class MainWindow_SA_label(QMainWindow):
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_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_:
@ -1171,7 +1179,7 @@ class MainWindow_SA_label(QMainWindow):
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_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_:
@ -1179,7 +1187,7 @@ class MainWindow_SA_label(QMainWindow):
self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_Start"], self.data.df_corrected.at[Config["EventLabelIndexList"][Config["PlotEventIndex"]], "correct_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":
@ -1187,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):
@ -1259,7 +1267,7 @@ class Data:
def open_file(self): def open_file(self):
if Path(Config["Path"]["Input_OrgBCG"]).is_file(): if Path(Config["Path"]["Input_OrgBCG"]).is_file():
Config["Path"]["Input_OrgBCG"] = str(Path(Config["Path"]["Input_orgBcg"]).parent) Config["Path"]["Input_OrgBCG"] = str(Path(Config["Path"]["Input_OrgBCG"]).parent)
if Path(Config["Path"]["Input_Tho"]).is_file(): if Path(Config["Path"]["Input_Tho"]).is_file():
Config["Path"]["Input_Tho"] = str(Path(Config["Path"]["Input_Tho"]).parent) Config["Path"]["Input_Tho"] = str(Path(Config["Path"]["Input_Tho"]).parent)
if Path(Config["Path"]["Input_Abd"]).is_file(): if Path(Config["Path"]["Input_Abd"]).is_file():
@ -1275,84 +1283,88 @@ 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)
if ((not Path(Config["Path"]["Input_OrgBCG"]).exists()) result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
or (not Path(Config["Path"]["Input_Tho"]).exists())
or (not Path(Config["Path"]["Input_Abd"]).exists())
or (not Path(Config["Path"]["Input_FlowT"]).exists())
or (not Path(Config["Path"]["Input_FlowP"]).exists())
or (not Path(Config["Path"]["Input_SpO2"]).exists())
or (not Path(Config["Path"]["Input_Artifact"]).exists())):
return Result().failure(info=Constants.INPUT_FAILURE +
Constants.FAILURE_REASON["Path_Not_Exist"])
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], ConfigParams.ORGBCG_SYNC)
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) 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) 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) 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) 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) 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"], Filename.ARTIFACT_A, Params.ENDSWITH_TXT)
if result.status:
Config["Path"]["Input_Artifact"] = result.data["path"]
else:
return result
Config["Path"]["Input_Artifact"] = str(
Path(Config["Path"]["Input_Artifact"]) / Path(ConfigParams.ARTIFACT_A + ConfigParams.ENDSWITH_TXT))
Config["Path"]["Input_Label"] = str( 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():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
Filename.ARTIFACT_A + "" +
Config["Path"]["Input_Artifact"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Label"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
Filename.SA_LABEL_SYNC + "" +
Config["Path"]["Input_Label"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
try: 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:
return Result().failure(info=Constants.INPUT_FAILURE + return Result().failure(info=Constants.INPUT_FAILURE +
@ -1360,13 +1372,7 @@ class Data:
try: try:
# 检查体动标签正确性,长度 # 检查体动标签正确性,长度
if len(self.Artifact) % 4 != 0: PublicFunc.examine_artifact(self.Artifact)
return Result().failure(info=Constants.INPUT_FAILURE +
Constants.FAILURE_REASON["Artifact_Format_Not_Correct"])
for i in range(0, len(self.Artifact), 4):
unit_data = self.Artifact[i:i + 4]
if len(unit_data) < 4:
break
self.Artifact = self.Artifact.reshape(-1, 4) self.Artifact = self.Artifact.reshape(-1, 4)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + return Result().failure(info=Constants.INPUT_FAILURE +
@ -1584,9 +1590,6 @@ class Data:
return Result().success(info=Constants.RESAMPLE_FINISHED) return Result().success(info=Constants.RESAMPLE_FINISHED)
def save(self): def save(self):
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
if self.df_corrected is None: if self.df_corrected is None:
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"]) return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
@ -1618,6 +1621,6 @@ class CustomNavigationToolbar(NavigationToolbar2QT):
def __init__(self, canvas, parent): 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,10 @@ 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 sklearn.linear_model import TheilSenRegressor from sklearn.linear_model import TheilSenRegressor
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
@ -99,11 +101,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
@ -112,15 +114,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_PSG_TEXT / "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": {}
@ -162,7 +164,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()
@ -173,31 +175,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))))
self.ui.plainTextEdit_file_path_save.setPlainText(
str((Path(self.root_path) /
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
Path(str(self.sampID)) /
Path(ConfigParams.APPROXIMATELY_ALIGN_INFO +
ConfigParams.ENDSWITH_CSV))))
class MainWindow_approximately_align(QMainWindow): class MainWindow_approximately_align(QMainWindow):
@ -998,19 +994,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) 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) 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) 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"]
@ -1019,13 +1015,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[
@ -1034,8 +1030,6 @@ class Data:
return Result().success(info=Constants.INPUT_FINISHED) return Result().success(info=Constants.INPUT_FINISHED)
def save(self, epoch): def save(self, epoch):
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
try: try:
pos = Config["pos"] pos = Config["pos"]
ApplyFrequency = Config["ApplyFrequency"] ApplyFrequency = Config["ApplyFrequency"]
@ -1120,10 +1114,7 @@ class Data:
def Standardize_2(self): def Standardize_2(self):
# 预重采样 # 预重采样
try: try:
# TODO这里的采样率处理如果THO和ABD的采样率不同可能还是会导致之后的ApplyFrequency出问题最后导致得到的粗同步坐标不正确
#
if Config["InputConfig"]["ThoFreq"] != Config["TempFrequency"]: if Config["InputConfig"]["ThoFreq"] != Config["TempFrequency"]:
print(int(Config["InputConfig"]["ThoFreq"]), int(Config["TempFrequency"]))
self.processed_Tho = resample(self.processed_Tho, self.processed_Tho = resample(self.processed_Tho,
int(Config["PSG_seconds"] * Config["TempFrequency"])) int(Config["PSG_seconds"] * Config["TempFrequency"]))
@ -1198,7 +1189,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()
@ -1293,8 +1284,8 @@ class Data:
epoch_max = response.data["epoch_max"] epoch_max = response.data["epoch_max"]
epoch_second = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"] epoch_second = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"]
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, append, sum as np_sum, nonzero
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
@ -35,7 +36,6 @@ ButtonState = {
"pushButton_prev_move": False, "pushButton_prev_move": False,
"pushButton_pause": False, "pushButton_pause": False,
"pushButton_next_move": False, "pushButton_next_move": False,
"pushButton_save": False,
"pushButton_type_1": False, "pushButton_type_1": False,
"pushButton_type_2": False, "pushButton_type_2": False,
"pushButton_type_3": False, "pushButton_type_3": False,
@ -49,7 +49,6 @@ ButtonState = {
"pushButton_prev_move": False, "pushButton_prev_move": False,
"pushButton_pause": False, "pushButton_pause": False,
"pushButton_next_move": False, "pushButton_next_move": False,
"pushButton_save": False,
"pushButton_type_1": False, "pushButton_type_1": False,
"pushButton_type_2": False, "pushButton_type_2": False,
"pushButton_type_3": False, "pushButton_type_3": False,
@ -80,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))))
} }
}) })
@ -127,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()
@ -138,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):
@ -233,11 +232,11 @@ class MainWindow_artifact_label(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0) self.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)
@ -261,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__)
@ -270,7 +269,6 @@ class MainWindow_artifact_label(QMainWindow):
self.ui.pushButton_type_3.clicked.connect(self.__slot_btn_label__) self.ui.pushButton_type_3.clicked.connect(self.__slot_btn_label__)
self.ui.pushButton_type_4.clicked.connect(self.__slot_btn_label__) self.ui.pushButton_type_4.clicked.connect(self.__slot_btn_label__)
self.ui.pushButton_type_5.clicked.connect(self.__slot_btn_label__) self.ui.pushButton_type_5.clicked.connect(self.__slot_btn_label__)
self.ui.pushButton_save.clicked.connect(self.__slot_btn_save__)
self.ui.pushButton_delete.clicked.connect(self.__slot_btn_delete_label__) self.ui.pushButton_delete.clicked.connect(self.__slot_btn_delete_label__)
self.ui.pushButton_prev_move.clicked.connect(self.__slot_btn_move__) self.ui.pushButton_prev_move.clicked.connect(self.__slot_btn_move__)
self.ui.pushButton_pause.clicked.connect(self.__slot_btn_move__) self.ui.pushButton_pause.clicked.connect(self.__slot_btn_move__)
@ -300,8 +298,10 @@ class MainWindow_artifact_label(QMainWindow):
del self.rectangles_ax0_patches del self.rectangles_ax0_patches
del self.rectangles_ax1_patches del self.rectangles_ax1_patches
del self.annotation_tableWidget del self.annotation_tableWidget
self.ax0.clear() if self.ax0 is not None:
self.ax1.clear() self.ax0.clear()
if self.ax1 is not None:
self.ax1.clear()
# 释放资源 # 释放资源
del self.data del self.data
@ -370,71 +370,71 @@ class MainWindow_artifact_label(QMainWindow):
if self.data.df_Artifact_a.iloc[i][1] == 1: if self.data.df_Artifact_a.iloc[i][1] == 1:
# 橙色,剧烈体动 # 橙色,剧烈体动
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:
# 黄色,脉冲体动 # 黄色,脉冲体动
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:
# 青色,常规体动 # 青色,常规体动
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:
# 紫色,疑似鼾声 # 紫色,疑似鼾声
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:
# 灰色,离床 # 灰色,离床
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:
@ -560,7 +560,7 @@ class MainWindow_artifact_label(QMainWindow):
except Exception as e: except Exception as e:
return Result().failure(info=Constants.UPDATE_FAILURE + Constants.FAILURE_REASON["Update_Info_Exception"] + "\n" + format_exc()) return Result().failure(info=Constants.UPDATE_FAILURE + Constants.FAILURE_REASON["Update_Info_Exception"] + "\n" + format_exc())
return Result().success(info=Constants.UPDATE_FAILURE) return Result().success(info=Constants.UPDATE_FINISHED)
def __slot_btn_input__(self): def __slot_btn_input__(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
@ -592,9 +592,6 @@ class MainWindow_artifact_label(QMainWindow):
else: else:
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_INFO)
self.__reset__()
PublicFunc.finish_operation(self, ButtonState)
# 获取存档 # 获取存档
PublicFunc.progressbar_update(self, 3, 6, Constants.LOADING_ARCHIVE, 50) PublicFunc.progressbar_update(self, 3, 6, Constants.LOADING_ARCHIVE, 50)
result = self.data.get_archive() result = self.data.get_archive()
@ -648,7 +645,6 @@ class MainWindow_artifact_label(QMainWindow):
ButtonState["Current"]["pushButton_prev_move"] = True ButtonState["Current"]["pushButton_prev_move"] = True
ButtonState["Current"]["pushButton_next_move"] = True ButtonState["Current"]["pushButton_next_move"] = True
ButtonState["Current"]["pushButton_pause"] = True ButtonState["Current"]["pushButton_pause"] = True
ButtonState["Current"]["pushButton_save"] = True
ButtonState["Current"]["pushButton_type_1"] = True ButtonState["Current"]["pushButton_type_1"] = True
ButtonState["Current"]["pushButton_type_2"] = True ButtonState["Current"]["pushButton_type_2"] = True
ButtonState["Current"]["pushButton_type_3"] = True ButtonState["Current"]["pushButton_type_3"] = True
@ -659,7 +655,12 @@ class MainWindow_artifact_label(QMainWindow):
def __slot_btn_label__(self): def __slot_btn_label__(self):
sender = self.sender() sender = self.sender()
flag = False flag = False
select_row = array([]).astype(dict) select_row = []
select_type = array([0, 0, 0, 0, 0])
flagf = False
flagb = False
start_time = 0
end_time = 0
if sender == self.ui.pushButton_type_1: if sender == self.ui.pushButton_type_1:
type = 1 type = 1
@ -682,65 +683,153 @@ class MainWindow_artifact_label(QMainWindow):
for index, row in self.data.df_Artifact_a.iterrows(): for index, row in self.data.df_Artifact_a.iterrows():
value_startTime = row['startTime'] value_startTime = row['startTime']
value_endTime = row['endTime'] value_endTime = row['endTime']
value_type = row['type']
# if ((value_endTime >= int(self.ui.lineEdit_start_time.text()) and value_startTime <= int(self.ui.lineEdit_start_time.text())) or if ((value_startTime <= int(self.ui.lineEdit_end_time.text()) <= value_endTime) or
# (value_endTime >= int(self.ui.lineEdit_end_time.text()) and value_startTime <= int(self.ui.lineEdit_end_time.text())) or (value_startTime <= int(self.ui.lineEdit_start_time.text()) <= value_endTime) or
# (value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(self.ui.lineEdit_end_time.text())) or (value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(self.ui.lineEdit_end_time.text())) or
# (value_startTime <= int(self.ui.lineEdit_start_time.text()) and value_endTime >= int(self.ui.lineEdit_end_time.text()))): (0 < (int(self.ui.lineEdit_start_time.text()) - value_endTime) <= (2 * Config["InputConfig"]["UseFreq"])) or
# select_row = append(select_row, row) (0 < (value_startTime - int(self.ui.lineEdit_end_time.text())) <= (2 * Config["InputConfig"]["UseFreq"]))):
select_row.append(row.to_dict())
if row['type'] == 1:
select_type[0] = select_type[0] + 1
elif row['type'] == 2:
select_type[1] = select_type[1] + 1
elif row['type'] == 3:
select_type[2] = select_type[2] + 1
elif row['type'] == 4:
select_type[3] = select_type[3] + 1
elif row['type'] == 5:
select_type[4] = select_type[4] + 1
if (0 < (int(self.ui.lineEdit_start_time.text()) - value_endTime) <= (2 * Config["InputConfig"]["UseFreq"])) and (value_type == type):
flagf = True
if (0 < (value_startTime - int(self.ui.lineEdit_end_time.text())) <= (2 * Config["InputConfig"]["UseFreq"])) and (value_type == type):
flagb = True
# TODO体动选取区域的判别尚未做的很完整选中多个已有的体动的区域时可能会出现问题 count = np_sum(select_type >= 1)
if (type == 1 and row['type'] == 1) or (type == 2 and row['type'] == 2) or (type == 3 and row['type'] == 3): if count >= 2 or (count == 1 and nonzero(select_type)[0][0] + 1 == type):
if ((value_startTime > int(self.ui.lineEdit_start_time.text()) and (value_startTime - int(self.ui.lineEdit_end_time.text()) <= 2 * Config["InputConfig"]["UseFreq"])) or if count >= 2:
(value_endTime < int(self.ui.lineEdit_end_time.text()) and (int(self.ui.lineEdit_end_time.text()) - value_endTime <= 2 * Config["InputConfig"]["UseFreq"]))): reply = QMessageBox.question(self, '确认',
reply = QMessageBox.question(self, '确认', '{}{},是否确认合并?'.format(Constants.ARTIFACT_LABEL_MERGE, row['number']), QMessageBox.Yes | QMessageBox.No, '{}{}'.format(Constants.ARTIFACT_LABEL_MULTIPLE_ARTIFACT_COVER_OR_DELETE, [d["number"] for d in select_row]),
QMessageBox.No) QMessageBox.Yes | QMessageBox.No,
if reply == QMessageBox.Yes: QMessageBox.No)
self.data.df_Artifact_a.loc[self.data.df_Artifact_a['number'] == row['number'], if reply == QMessageBox.No:
['number', 'type', 'startTime', 'endTime']] = [ return
int(row['number']),
int(type),
int(self.ui.lineEdit_start_time.text()) if int(self.ui.lineEdit_start_time.text()) < int(row['startTime']) else int(row['startTime']),
int(self.ui.lineEdit_end_time.text()) if int(self.ui.lineEdit_end_time.text()) > int(row['endTime']) else int(row['endTime'])
]
new_row = {'number': int(row['number']),
'type': int(type),
'startTime': int(self.ui.lineEdit_start_time.text()),
'endTime': int(self.ui.lineEdit_end_time.text())}
flag = True
break
else:
return
if value_startTime <= int(self.ui.lineEdit_end_time.text()) and int(
self.ui.lineEdit_start_time.text()) <= value_endTime:
PublicFunc.msgbox_output(self, f"{Constants.ARTIFACT_LABEL_OVERLAPPING}{row['number']}", Constants.MSGBOX_TYPE_ERROR)
return
if not flag: if flagf == True and flagb == False:
new_row = {'number': int(len(self.data.df_Artifact_a) + 1), if type == 1 or type == 2 or type == 3:
'type': int(type), PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE,
'startTime': int(self.ui.lineEdit_start_time.text()), Constants.MSGBOX_TYPE_INFO)
'endTime': int(self.ui.lineEdit_end_time.text())} start_time = select_row[0]['startTime']
self.data.df_Artifact_a = concat([self.data.df_Artifact_a, DataFrame([new_row])], ignore_index=True) end_time = int(self.ui.lineEdit_end_time.text())
sorted_part = self.data.df_Artifact_a[['type', 'startTime', 'endTime']].sort_values(by='startTime').reset_index( elif type == 4 or type == 5:
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_WARNING,
Constants.MSGBOX_TYPE_INFO)
select_row = select_row[1:]
start_time = int(self.ui.lineEdit_start_time.text())
end_time = int(self.ui.lineEdit_end_time.text())
if flagf == False and flagb == True:
if type == 1 or type == 2 or type == 3:
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE,
Constants.MSGBOX_TYPE_INFO)
start_time = int(self.ui.lineEdit_start_time.text())
end_time = select_row[-1]['endTime']
elif type == 4 or type == 5:
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_WARNING,
Constants.MSGBOX_TYPE_INFO)
select_row = select_row[:-1]
start_time = int(self.ui.lineEdit_start_time.text())
end_time = int(self.ui.lineEdit_end_time.text())
if flagf == True and flagb == True:
if type == 1 or type == 2 or type == 3:
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE,
Constants.MSGBOX_TYPE_INFO)
start_time = select_row[0]['startTime']
end_time = select_row[-1]['endTime']
elif type == 4 or type == 5:
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_WARNING,
Constants.MSGBOX_TYPE_INFO)
select_row = select_row[1:-1]
start_time = int(self.ui.lineEdit_start_time.text())
end_time = int(self.ui.lineEdit_end_time.text())
if flagf == False and flagb == False:
start_time = int(self.ui.lineEdit_start_time.text())
end_time = int(self.ui.lineEdit_end_time.text())
for select_each_row in select_row:
self.data.df_Artifact_a = self.data.df_Artifact_a[self.data.df_Artifact_a['number'] != select_each_row["number"]]
else:
select_row = []
select_type = array([0, 0, 0, 0, 0])
for index, row in self.data.df_Artifact_a.iterrows():
value_startTime = row['startTime']
value_endTime = row['endTime']
value_type = row['type']
if ((value_startTime <= int(self.ui.lineEdit_end_time.text()) <= value_endTime) or
(value_startTime <= int(self.ui.lineEdit_start_time.text()) <= value_endTime) or
(value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(
self.ui.lineEdit_end_time.text()))):
select_row.append(row.to_dict())
if row['type'] == 1:
select_type[0] = select_type[0] + 1
elif row['type'] == 2:
select_type[1] = select_type[1] + 1
elif row['type'] == 3:
select_type[2] = select_type[2] + 1
elif row['type'] == 4:
select_type[3] = select_type[3] + 1
elif row['type'] == 5:
select_type[4] = select_type[4] + 1
count = np_sum(select_type >= 1)
if (count == 1 and nonzero(select_type)[0][0] + 1 != type):
reply = QMessageBox.question(self, '确认',
'{}{}'.format(Constants.ARTIFACT_LABEL_SINGLE_TYPE_NOT_EQUAL,
[d["number"] for d in select_row]),
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No)
if reply == QMessageBox.No:
return
start_time = int(self.ui.lineEdit_start_time.text())
end_time = int(self.ui.lineEdit_end_time.text())
for select_each_row in select_row:
self.data.df_Artifact_a = self.data.df_Artifact_a[self.data.df_Artifact_a['number'] != select_each_row["number"]]
elif count == 0:
start_time = int(self.ui.lineEdit_start_time.text())
end_time = int(self.ui.lineEdit_end_time.text())
else:
raise ValueError("count值不存在")
new_row = {
'number': 1,
'type': int(type),
'startTime': start_time,
'endTime': end_time
}
self.data.df_Artifact_a = concat([self.data.df_Artifact_a, DataFrame([new_row])], ignore_index=True)
self.data.df_Artifact_a[['type', 'startTime', 'endTime']] = self.data.df_Artifact_a[['type', 'startTime', 'endTime']].sort_values(by='startTime').reset_index(
drop=True) drop=True)
self.data.df_Artifact_a[['type', 'startTime', 'endTime']] = sorted_part self.data.df_Artifact_a['number'] = range(1, len(self.data.df_Artifact_a) + 1)
self.update_tableWidget() self.update_tableWidget()
self.update_Info() self.update_Info()
self.__plot_artifact__() self.__plot_artifact__()
target_row = self.data.df_Artifact_a[ target_row = self.data.df_Artifact_a[self.data.df_Artifact_a.eq(start_time).any(axis=1)]
self.data.df_Artifact_a.eq(int(self.ui.lineEdit_start_time.text())).any(axis=1)]
if not target_row.empty: if not target_row.empty:
first_column_value = target_row.iloc[0, 0] # 获取第1列的值 first_column_value = target_row.iloc[0, 0] # 获取第1列的值
else: else:
raise AttributeError() raise AttributeError()
PublicFunc.text_output(self.ui, f"新增体动标签{first_column_value}, 类型{new_row['type']},从{int(self.ui.lineEdit_start_time.text())}ms到{int(self.ui.lineEdit_end_time.text())}ms", Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, f"新增体动标签{first_column_value}, 类型{new_row['type']},从{int(start_time)}ms到{int(end_time)}ms", Constants.TIPS_TYPE_INFO)
self.__slot_btn_save__() self.save()
def __slot_btn_save__(self): def save(self):
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
# 保存 # 保存
@ -791,7 +880,7 @@ class MainWindow_artifact_label(QMainWindow):
self.update_tableWidget() self.update_tableWidget()
self.update_Info() self.update_Info()
self.__plot_artifact__() self.__plot_artifact__()
self.__slot_btn_save__() self.save()
PublicFunc.text_output(self.ui, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY}", Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY}", Constants.TIPS_TYPE_INFO)
else: else:
PublicFunc.text_output(self.ui, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE}", Constants.TIPS_TYPE_ERROR) PublicFunc.text_output(self.ui, f"{self.pressed_number}{Constants.ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE}", Constants.TIPS_TYPE_ERROR)
@ -929,13 +1018,15 @@ class MainWindow_artifact_label(QMainWindow):
PublicFunc.text_output(self.ui, f"{Constants.ARTIFACT_LABEL_JUMP_ARTIFACT}{str(self.pressed_number)}", Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, f"{Constants.ARTIFACT_LABEL_JUMP_ARTIFACT}{str(self.pressed_number)}", Constants.TIPS_TYPE_INFO)
def reset_axes(self): def reset_axes(self):
self.ax0.clear() if self.ax0 is not None:
self.ax1.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)
self.ax1.grid(True) if self.ax1 is not None:
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax1.clear()
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
def on_xlim_change(self, event_ax): def on_xlim_change(self, event_ax):
try: try:
@ -1208,17 +1299,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)
if (not Path(Config["Path"]["Input_orgBcg"]).exists()) or (not Path(Config["Path"]["Input_BCG"]).exists()): result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], Filename.ORGBCG_SYNC, Params.ENDSWITH_TXT)
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
result = PublicFunc.examine_file(Config["Path"]["Input_orgBcg"], ConfigParams.ORGBCG_SYNC)
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) 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"]
@ -1226,18 +1314,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 + 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 + 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 + 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())
@ -1271,7 +1359,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:
# 检查体动标签正确性,长度 # 检查体动标签正确性,长度
@ -1290,13 +1378,6 @@ class Data:
return Result().success(info=Constants.ARCHIVE_EXIST) return Result().success(info=Constants.ARCHIVE_EXIST)
def save(self, amount, duration): def save(self, amount, duration):
if (not Path(Config["Path"]["Save_a"]).parent.exists()) or (not Path(Config["Path"]["Save_a"]).parent.is_dir()):
Path(Config["Path"]["Save_a"]).parent.mkdir(parents=True, exist_ok=True)
if (not Path(Config["Path"]["Save_b"]).parent.exists()) or (not Path(Config["Path"]["Save_b"]).parent.is_dir()):
Path(Config["Path"]["Save_b"]).parent.mkdir(parents=True, exist_ok=True)
if (not Path(Config["Path"]["Save_c"]).parent.exists()) or (not Path(Config["Path"]["Save_c"]).parent.is_dir()):
Path(Config["Path"]["Save_c"]).parent.mkdir(parents=True, exist_ok=True)
try: try:
# Artifact_a.txt和Artifact_c.csv的内容遍历 # Artifact_a.txt和Artifact_c.csv的内容遍历
output_lines = [] output_lines = []
@ -1317,7 +1398,7 @@ class Data:
self.df_Artifact_a.to_csv(Path(Config["Path"]["Save_a"]), header=False, index=False, sep='\n') 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())
@ -1331,19 +1412,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

File diff suppressed because it is too large Load Diff

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) 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:
@ -322,9 +323,6 @@ class Data:
return Result().success(info=Constants.CUT_PSG_ALIGN_LABEL_FINISHED) return Result().success(info=Constants.CUT_PSG_ALIGN_LABEL_FINISHED)
def save(self): def save(self):
if (not Path(Config["Path"]["SaveFolder"]).exists()) or (not Path(Config["Path"]["SaveFolder"]).is_dir()):
Path(Config["Path"]["SaveFolder"]).mkdir(parents=True, exist_ok=True)
for raw in self.raw.values(): for raw in self.raw.values():
if len(raw) == 0: if len(raw) == 0:
return Result().failure(info=Constants.SAVE_FAILURE + return Result().failure(info=Constants.SAVE_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_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)
@ -204,7 +205,8 @@ class MainWindow_detect_Jpeak(QMainWindow):
QApplication.processEvents() QApplication.processEvents()
# 清空画框 # 清空画框
self.ax0.clear() if self.ax0 is not None:
self.ax0.clear()
# 释放资源 # 释放资源
del self.data del self.data
@ -354,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)
@ -378,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()
@ -397,21 +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)
if not Path(Config["Path"]["Input"]).exists(): result = PublicFunc.examine_file(Config["Path"]["Input"], Filename.BCG_FILTER, Params.ENDSWITH_TXT)
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
result = PublicFunc.examine_file(Config["Path"]["Input"], ConfigParams.BCG_FILTER)
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 +
@ -461,9 +460,6 @@ class Data:
return Result().success(info=Constants.DETECT_JPEAK_PREDICT_FINISHED) return Result().success(info=Constants.DETECT_JPEAK_PREDICT_FINISHED)
def save(self, chunk): def save(self, chunk):
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
if self.peak is None: if self.peak is None:
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"]) return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])

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)
@ -197,8 +198,10 @@ class MainWindow_detect_Rpeak(QMainWindow):
QApplication.processEvents() QApplication.processEvents()
# 清空画框 # 清空画框
self.ax0.clear() if self.ax0 is not None:
self.ax1.clear() self.ax0.clear()
if self.ax1 is not None:
self.ax1.clear()
# 释放资源 # 释放资源
del self.data del self.data
@ -349,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)
@ -374,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()
@ -397,21 +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)
if not Path(Config["Path"]["Input"]).exists(): result = PublicFunc.examine_file(Config["Path"]["Input"], Filename.ECG_FILTER, Params.ENDSWITH_TXT)
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
result = PublicFunc.examine_file(Config["Path"]["Input"], ConfigParams.ECG_FILTER)
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 +
@ -452,9 +452,6 @@ class Data:
return Result().success(info=Constants.DETECT_RPEAK_PREDICT_FINISHED) return Result().success(info=Constants.DETECT_RPEAK_PREDICT_FINISHED)
def save(self, chunk): def save(self, chunk):
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
if self.peak is None: if self.peak is None:
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"]) return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])

View File

@ -9,14 +9,15 @@ 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 append, delete, arange from numpy import append, delete, arange, setdiff1d
from overrides import overrides from overrides import overrides
from pandas import read_csv, DataFrame 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
@ -34,16 +35,14 @@ ButtonState = {
"pushButton_input": True, "pushButton_input": True,
"pushButton_prev_move": False, "pushButton_prev_move": False,
"pushButton_pause": False, "pushButton_pause": False,
"pushButton_next_move": False, "pushButton_next_move": False
"pushButton_save": False
}, },
"Current": { "Current": {
"pushButton_input_setting": True, "pushButton_input_setting": True,
"pushButton_input": True, "pushButton_input": True,
"pushButton_prev_move": False, "pushButton_prev_move": False,
"pushButton_pause": False, "pushButton_pause": False,
"pushButton_next_move": False, "pushButton_next_move": False
"pushButton_save": False
} }
} }
@ -71,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
@ -83,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
@ -97,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
@ -149,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()
@ -161,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("模式不存在")
@ -283,11 +282,11 @@ class MainWindow_label_check(QMainWindow):
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0) self.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)
@ -307,7 +306,6 @@ class MainWindow_label_check(QMainWindow):
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__) self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
self.ui.pushButton_input_setting.clicked.connect(self.setting.show) self.ui.pushButton_input_setting.clicked.connect(self.setting.show)
self.ui.pushButton_save.clicked.connect(self.__slot_btn_save__)
self.ui.pushButton_prev_move.clicked.connect(self.__slot_btn_move__) self.ui.pushButton_prev_move.clicked.connect(self.__slot_btn_move__)
self.ui.pushButton_pause.clicked.connect(self.__slot_btn_move__) self.ui.pushButton_pause.clicked.connect(self.__slot_btn_move__)
self.ui.pushButton_next_move.clicked.connect(self.__slot_btn_move__) self.ui.pushButton_next_move.clicked.connect(self.__slot_btn_move__)
@ -340,8 +338,10 @@ class MainWindow_label_check(QMainWindow):
del self.point_peak_original del self.point_peak_original
del self.point_peak_corrected del self.point_peak_corrected
del self.annotation_tableWidget del self.annotation_tableWidget
self.ax0.clear() if self.ax0 is not None:
self.ax1.clear() self.ax0.clear()
if self.ax1 is not None:
self.ax1.clear()
# 释放资源 # 释放资源
del self.data del self.data
@ -464,70 +464,81 @@ class MainWindow_label_check(QMainWindow):
self.data = Data() self.data = Data()
# 导入数据 # 导入数据
PublicFunc.progressbar_update(self, 1, 6, Constants.INPUTTING_DATA, 0) PublicFunc.progressbar_update(self, 1, 7, Constants.INPUTTING_DATA, 0)
result = self.data.open_file() result = self.data.open_file()
if not result.status: if not result.status:
PublicFunc.text_output(self.ui, "(1/6)" + result.info, Constants.TIPS_TYPE_ERROR) PublicFunc.text_output(self.ui, "(1/7)" + result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
return return
else: else:
PublicFunc.text_output(self.ui, "(1/6)" + result.info, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, "(1/7)" + result.info, Constants.TIPS_TYPE_INFO)
# 获取存档 # 获取存档
PublicFunc.progressbar_update(self, 2, 6, Constants.LOADING_ARCHIVE, 20) PublicFunc.progressbar_update(self, 2, 7, Constants.LOADING_ARCHIVE, 20)
result = self.data.get_archive() result = self.data.get_archive()
if not result.status: if not result.status:
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_ERROR) PublicFunc.text_output(self.ui, "(2/7)" + result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
return return
else: else:
PublicFunc.text_output(self.ui, "(2/6)" + result.info, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, "(2/7)" + result.info, Constants.TIPS_TYPE_INFO)
# 保存
PublicFunc.progressbar_update(self, 3, 7, Constants.SAVING_DATA, 25)
result = self.data.save()
if not result.status:
PublicFunc.text_output(self.ui, "(3/7)" + result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(3/7)" + result.info, Constants.TIPS_TYPE_INFO)
# 数据预处理 # 数据预处理
PublicFunc.progressbar_update(self, 3, 6, Constants.PREPROCESSING_DATA, 30) PublicFunc.progressbar_update(self, 4, 7, Constants.PREPROCESSING_DATA, 30)
result = self.data.preprocess() result = self.data.preprocess()
if not result.status: if not result.status:
PublicFunc.text_output(self.ui, "(3/6)" + result.info, Constants.TIPS_TYPE_ERROR) PublicFunc.text_output(self.ui, "(4/7)" + result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
return return
else: else:
PublicFunc.text_output(self.ui, "(3/6)" + result.info, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, "(4/7)" + result.info, Constants.TIPS_TYPE_INFO)
# 更新表格 # 更新表格
PublicFunc.progressbar_update(self, 4, 6, Constants.UPDATING_TABLEWIDGET_AND_INFO, 50) PublicFunc.progressbar_update(self, 5, 7, Constants.UPDATING_TABLEWIDGET_AND_INFO, 50)
result = self.__update_tableWidget_and_info__() result = self.__update_tableWidget_and_info__()
if not result.status: if not result.status:
PublicFunc.text_output(self.ui, "(4/6)" + result.info, Constants.TIPS_TYPE_ERROR) PublicFunc.text_output(self.ui, "(5/7)" + result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
return return
else: else:
PublicFunc.text_output(self.ui, "(4/6)" + result.info, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, "(5/7)" + result.info, Constants.TIPS_TYPE_INFO)
# 绘图 # 绘图
PublicFunc.progressbar_update(self, 5, 6, Constants.DRAWING_DATA, 60) PublicFunc.progressbar_update(self, 6, 7, Constants.DRAWING_DATA, 60)
result = self.__plot__() result = self.__plot__()
if not result.status: if not result.status:
PublicFunc.text_output(self.ui, "(5/6)" + result.info, Constants.TIPS_TYPE_ERROR) PublicFunc.text_output(self.ui, "(6/7)" + result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
return return
else: else:
PublicFunc.text_output(self.ui, "(5/6)" + result.info, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, "(6/7)" + result.info, Constants.TIPS_TYPE_INFO)
# 绘点 # 绘点
PublicFunc.progressbar_update(self, 6, 6, Constants.DRAWING_DATA, 80) PublicFunc.progressbar_update(self, 7, 7, Constants.DRAWING_DATA, 80)
result = self.__plot_peaks__() result = self.__plot_peaks__()
if not result.status: if not result.status:
PublicFunc.text_output(self.ui, "(6/6)" + result.info, Constants.TIPS_TYPE_ERROR) PublicFunc.text_output(self.ui, "(7/7)" + result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
return return
else: else:
PublicFunc.text_output(self.ui, "(6/6)" + result.info, Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, "(7/7)" + result.info, Constants.TIPS_TYPE_INFO)
self.__reset__() self.__reset__()
self.canvas.mpl_connect("motion_notify_event", self.on_motion) self.canvas.mpl_connect("motion_notify_event", self.on_motion)
@ -539,42 +550,8 @@ class MainWindow_label_check(QMainWindow):
ButtonState["Current"]["pushButton_prev_move"] = True ButtonState["Current"]["pushButton_prev_move"] = True
ButtonState["Current"]["pushButton_next_move"] = True ButtonState["Current"]["pushButton_next_move"] = True
ButtonState["Current"]["pushButton_pause"] = True ButtonState["Current"]["pushButton_pause"] = True
ButtonState["Current"]["pushButton_save"] = True
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_save__(self):
reply = QMessageBox.question(self, Constants.QUESTION_TITLE,
Constants.QUESTION_CONTENT + Config["Path"]["Save"],
QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes)
if reply == QMessageBox.Yes:
PublicFunc.__disableAllButton__(self, ButtonState)
# 保存
PublicFunc.progressbar_update(self, 1, 1, Constants.SAVING_DATA, 0)
total_rows = len(DataFrame(self.data.corrected_peak.reshape(-1)))
chunk_size = ConfigParams.LABEL_CHECK_SAVE_CHUNK_SIZE
with open(Config["Path"]["Save"], 'w') as f:
for start in range(0, total_rows, chunk_size):
end = min(start + chunk_size, total_rows)
chunk = DataFrame(self.data.corrected_peak.reshape(-1)).iloc[start:end]
result = self.data.save(chunk)
progress = int((end / total_rows) * 100)
self.progressbar.setValue(progress)
QApplication.processEvents()
if not result.status:
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.msgbox_output(self, result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_move__(self): def __slot_btn_move__(self):
if self.data is None: if self.data is None:
return return
@ -670,13 +647,15 @@ class MainWindow_label_check(QMainWindow):
PublicFunc.text_output(self.ui, f"{Constants.LABEL_CHECK_JUMP_X_INDEX}{str(int(x))}", Constants.TIPS_TYPE_INFO) PublicFunc.text_output(self.ui, f"{Constants.LABEL_CHECK_JUMP_X_INDEX}{str(int(x))}", Constants.TIPS_TYPE_INFO)
def reset_axes(self): def reset_axes(self):
self.ax0.clear() if self.ax0 is not None:
self.ax1.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)
self.ax1.grid(True) if self.ax1 is not None:
self.ax1.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax1.clear()
self.ax1.grid(True)
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
def on_xlim_change(self, event_ax): def on_xlim_change(self, event_ax):
try: try:
@ -814,6 +793,7 @@ class MainWindow_label_check(QMainWindow):
height=Config["FindPeaks"]["MinHeight"], height=Config["FindPeaks"]["MinHeight"],
distance=Config["FindPeaks"]["MinInterval"]) distance=Config["FindPeaks"]["MinInterval"])
peaks_idx = peaks_idx + int(rect_left) peaks_idx = peaks_idx + int(rect_left)
peaks_idx = setdiff1d(peaks_idx, self.data.corrected_peak)
if len(peaks_idx) != 0: if len(peaks_idx) != 0:
PublicFunc.text_output(self.ui, f"{Constants.LABEL_CHECK_ADD_POINTS_SUCCESSFULLY}{peaks_idx}", PublicFunc.text_output(self.ui, f"{Constants.LABEL_CHECK_ADD_POINTS_SUCCESSFULLY}{peaks_idx}",
Constants.TIPS_TYPE_INFO) Constants.TIPS_TYPE_INFO)
@ -843,7 +823,14 @@ class MainWindow_label_check(QMainWindow):
self.data.corrected_peak.sort() self.data.corrected_peak.sort()
self.data.corrected_peak_y = [self.data.processed_data[x] for x in self.data.corrected_peak] self.data.corrected_peak_y = [self.data.processed_data[x] for x in self.data.corrected_peak]
self.__update_tableWidget_and_info__() self.__update_tableWidget_and_info__()
DataFrame(self.data.corrected_peak).to_csv(Config["Path"]["Save"], index=False, header=False) result = self.data.save()
if not result.status:
PublicFunc.text_output(self.ui, result.info, Constants.TIPS_TYPE_ERROR)
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
else:
PublicFunc.text_output(self.ui, result.info, Constants.TIPS_TYPE_INFO)
# 移除矩形patch # 移除矩形patch
if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None: if self.figToolbar.rect_patch_ax0 is not None and self.figToolbar.rect_patch_ax1 is not None:
self.figToolbar.rect_patch_ax0.remove() self.figToolbar.rect_patch_ax0.remove()
@ -860,24 +847,24 @@ 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)
# 如果矩形patch不存在则创建一个新的 # 如果矩形patch不存在则创建一个新的
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)
# 更新矩形patch的位置和大小 # 更新矩形patch的位置和大小
@ -908,13 +895,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():
@ -926,28 +913,38 @@ 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) 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["Path"]["Input_Peak"] = str(
Path(Config["Path"]["Input_Peak"]) / Path(peak + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
Config["InputConfig"]["Freq"] = result.data["freq"] Config["InputConfig"]["Freq"] = result.data["freq"]
Config["Path"]["Input_Approximately_Align"] = str(
Path(Config["Path"]["Input_Approximately_Align"]) / Path(ConfigParams.APPROXIMATELY_ALIGN_INFO + ConfigParams.ENDSWITH_CSV))
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(save + str(Config["InputConfig"]["Freq"]) + ConfigParams.ENDSWITH_TXT))
else: else:
return result return result
if (not Path(Config["Path"]["Input_Signal"]).exists()) or (not Path(Config["Path"]["Input_Peak"]).exists()): Config["Path"]["Input_Peak"] = str(
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"]) Path(Config["Path"]["Input_Peak"]) / Path(peak + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Input_Approximately_Align"] = str(
Path(Config["Path"]["Input_Approximately_Align"]) / Path(
Filename.APPROXIMATELY_ALIGN_INFO + Params.ENDSWITH_CSV))
Config["Path"]["Save"] = str(
Path(Config["Path"]["Save"]) / Path(save + str(Config["InputConfig"]["Freq"]) + Params.ENDSWITH_TXT))
if not Path(Config["Path"]["Input_Peak"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
peak + "" +
Config["Path"]["Input_Peak"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
Filename.APPROXIMATELY_ALIGN_INFO + "" +
Config["Path"]["Input_Approximately_Align"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
try: 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 +
@ -979,7 +976,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)
@ -1010,15 +1007,12 @@ class Data:
return Result().success(info=Constants.PREPROCESS_FINISHED) return Result().success(info=Constants.PREPROCESS_FINISHED)
def save(self, chunk): def save(self):
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
if self.corrected_peak is None: if self.corrected_peak is None:
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"]) return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
try: try:
chunk.to_csv(Config["Path"]["Save"], mode='a', index=False, header=False) DataFrame(self.corrected_peak).to_csv(Config["Path"]["Save"], index=False, header=False)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.SAVE_FAILURE + return Result().failure(info=Constants.SAVE_FAILURE +
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc()) Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
@ -1032,19 +1026,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

@ -16,9 +16,12 @@ from func.Module_label_check import MainWindow_label_check
from func.Module_precisely_align import MainWindow_precisely_align from func.Module_precisely_align import MainWindow_precisely_align
from func.Module_cut_PSG import MainWindow_cut_PSG from func.Module_cut_PSG import MainWindow_cut_PSG
from func.Module_artifact_label import MainWindow_artifact_label from func.Module_artifact_label import MainWindow_artifact_label
from func.Module_bcg_quality_label import MainWindow_bcg_quality_label
from func.Module_resp_quality_label import MainWindow_resp_quality_label
from func.Module_SA_label import MainWindow_SA_label from func.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")
@ -52,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
@ -62,7 +65,8 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.precisely_align = None self.precisely_align = None
self.cut_PSG = None self.cut_PSG = None
self.artifact_label = None self.artifact_label = None
self.bcg_quality_label = None
self.resp_quality_label = None
self.SA_label = None self.SA_label = None
# 绑定槽函数 # 绑定槽函数
@ -77,22 +81,24 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.ui.pushButton_precisely_align.clicked.connect(self.__slot_btn_precisely_align__) self.ui.pushButton_precisely_align.clicked.connect(self.__slot_btn_precisely_align__)
self.ui.pushButton_cut_PSG.clicked.connect(self.__slot_btn_cut_PSG__) self.ui.pushButton_cut_PSG.clicked.connect(self.__slot_btn_cut_PSG__)
self.ui.pushButton_artifact_label.clicked.connect(self.__slot_btn_artifact_label__) self.ui.pushButton_artifact_label.clicked.connect(self.__slot_btn_artifact_label__)
self.ui.pushButton_bcg_quality_label.clicked.connect(self.__slot_btn_bcg_quality_label__)
self.ui.pushButton_resp_quality_label.clicked.connect(self.__slot_btn_resp_quality_label__)
self.ui.pushButton_SA_label.clicked.connect(self.__slot_btn_SA_label__) self.ui.pushButton_SA_label.clicked.connect(self.__slot_btn_SA_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):
@ -100,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])
# 修改配置 # 修改配置
@ -120,6 +126,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.approximately_align.show(root_path, int(sampID)) self.approximately_align.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率 # 默认最大化显示而非固定分辨率
self.approximately_align.showMaximized() self.approximately_align.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_preprocess__(self): def __slot_btn_preprocess__(self):
self.preprocess = MainWindow_preprocess() self.preprocess = MainWindow_preprocess()
@ -140,6 +147,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.preprocess.show(mode, root_path, int(sampID)) self.preprocess.show(mode, root_path, int(sampID))
# 默认最大化显示而非固定分辨率 # 默认最大化显示而非固定分辨率
self.preprocess.showMaximized() self.preprocess.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_detect_Jpeak__(self): def __slot_btn_detect_Jpeak__(self):
self.detect_Jpeak = MainWindow_detect_Jpeak() self.detect_Jpeak = MainWindow_detect_Jpeak()
@ -152,6 +160,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.detect_Jpeak.show(root_path, int(sampID)) self.detect_Jpeak.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率 # 默认最大化显示而非固定分辨率
self.detect_Jpeak.showMaximized() self.detect_Jpeak.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_detect_Rpeak__(self): def __slot_btn_detect_Rpeak__(self):
self.detect_Rpeak = MainWindow_detect_Rpeak() self.detect_Rpeak = MainWindow_detect_Rpeak()
@ -164,6 +173,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.detect_Rpeak.show(root_path, int(sampID)) self.detect_Rpeak.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率 # 默认最大化显示而非固定分辨率
self.detect_Rpeak.showMaximized() self.detect_Rpeak.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_label_check__(self): def __slot_btn_label_check__(self):
self.label_check = MainWindow_label_check() self.label_check = MainWindow_label_check()
@ -186,7 +196,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.label_check.show(mode, root_path, int(sampID)) self.label_check.show(mode, root_path, int(sampID))
# 默认最大化显示而非固定分辨率 # 默认最大化显示而非固定分辨率
self.label_check.showMaximized() self.label_check.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_precisely_align__(self): def __slot_btn_precisely_align__(self):
self.precisely_align = MainWindow_precisely_align() self.precisely_align = MainWindow_precisely_align()
@ -199,6 +209,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.precisely_align.show(root_path, int(sampID)) self.precisely_align.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率 # 默认最大化显示而非固定分辨率
self.precisely_align.showMaximized() self.precisely_align.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_cut_PSG__(self): def __slot_btn_cut_PSG__(self):
self.cut_PSG = MainWindow_cut_PSG() self.cut_PSG = MainWindow_cut_PSG()
@ -209,6 +220,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
if not self.check_sampID(): if not self.check_sampID():
return return
self.cut_PSG.show(root_path, int(sampID)) self.cut_PSG.show(root_path, int(sampID))
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_artifact_label__(self): def __slot_btn_artifact_label__(self):
self.artifact_label = MainWindow_artifact_label() self.artifact_label = MainWindow_artifact_label()
@ -221,6 +233,33 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.artifact_label.show(root_path, int(sampID)) self.artifact_label.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率 # 默认最大化显示而非固定分辨率
self.artifact_label.showMaximized() self.artifact_label.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_bcg_quality_label__(self):
self.bcg_quality_label = MainWindow_bcg_quality_label()
root_path = self.ui.plainTextEdit_root_path.toPlainText()
sampID = self.ui.comboBox_sampID.currentText()
if not self.check_root_path():
return
if not self.check_sampID():
return
self.bcg_quality_label.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率
self.bcg_quality_label.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_resp_quality_label__(self):
self.resp_quality_label = MainWindow_resp_quality_label()
root_path = self.ui.plainTextEdit_root_path.toPlainText()
sampID = self.ui.comboBox_sampID.currentText()
if not self.check_root_path():
return
if not self.check_sampID():
return
self.resp_quality_label.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率
self.resp_quality_label.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def __slot_btn_SA_label__(self): def __slot_btn_SA_label__(self):
self.SA_label = MainWindow_SA_label() self.SA_label = MainWindow_SA_label()
@ -233,6 +272,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
self.SA_label.show(root_path, int(sampID)) self.SA_label.show(root_path, int(sampID))
# 默认最大化显示而非固定分辨率 # 默认最大化显示而非固定分辨率
self.SA_label.showMaximized() self.SA_label.showMaximized()
self.check_save_path_and_mkdir(root_path, sampID)
def seek_sampID(self, path): def seek_sampID(self, path):
if not Path(path).exists(): if not Path(path).exists():
@ -242,7 +282,6 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
sub_folders = [item.name for item in Path(path).iterdir() if item.is_dir()] sub_folders = [item.name for item in Path(path).iterdir() if item.is_dir()]
self.ui.comboBox_sampID.addItems(sub_folders) self.ui.comboBox_sampID.addItems(sub_folders)
def check_root_path(self): def check_root_path(self):
if self.ui.plainTextEdit_root_path.toPlainText() == Constants.STRING_IS_EMPTY: if self.ui.plainTextEdit_root_path.toPlainText() == Constants.STRING_IS_EMPTY:
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR)
@ -254,3 +293,16 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_SAMPID_EMPTY, Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, Constants.MAINWINDOW_SAMPID_EMPTY, Constants.MSGBOX_TYPE_ERROR)
return False return False
return True return True
def check_save_path_and_mkdir(self, root_path, sampID):
path_Label = Path(root_path) / Path(Filename.PATH_LABEL) / Path(str(sampID))
path_OrgBCG_Aligned = Path(root_path) / Path(Filename.PATH_ORGBCG_ALIGNED) / Path(str(sampID))
path_PSG_Aligned = Path(root_path) / Path(Filename.PATH_PSG_ALIGNED) / Path(str(sampID))
path_OrgBCG_Text = Path(root_path) / Path(Filename.PATH_ORGBCG_TEXT) / Path(str(sampID))
path_PSG_Text = Path(root_path) / Path(Filename.PATH_PSG_TEXT) / Path(str(sampID))
path_list = [path_Label, path_OrgBCG_Aligned, path_PSG_Aligned, path_OrgBCG_Text, path_PSG_Text]
for path in path_list:
if not path.exists():
path.mkdir(parents=True, exist_ok=True)

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_PSG_TEXT / "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)
@ -687,7 +688,7 @@ class MainWindow_precisely_align(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def __slot_btn_calculate_correlation__(self, test1=None, shift_front=None, shift_back=None): def __slot_btn_calculate_correlation__(self, test1=None, shift_front=None, shift_back=None):
# TODO这里有个未知的BUG虽然不影响功能但会影响代码整洁性第一个形参赋值为None时之后使用变量时将会变成False不知道为什么 # TODO这里有个未知的BUG虽然不影响功能但会影响代码整洁性第一个形参赋值为None时之后使用变量时将会变成False不知道为什么
PublicFunc.__disableAllButton__(self, ButtonState) PublicFunc.__disableAllButton__(self, ButtonState)
sender = self.sender() sender = self.sender()
@ -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,26 +1328,26 @@ 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)
if self.ui.radioButton_BCG_front.isChecked(): if self.ui.radioButton_BCG_front.isChecked():
@ -1454,72 +1455,83 @@ 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) 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"]
Config["Path"]["Input_Approximately_Align"] = str(
Path(Config["Path"]["Input_Approximately_Align"]) / Path(
ConfigParams.APPROXIMATELY_ALIGN_INFO + ConfigParams.ENDSWITH_CSV))
Config["Path"]["Save_AlignInfo"] = str(
Path(Config["Path"]["Save_AlignInfo"]) / Path(
ConfigParams.PRECISELY_ALIGN_INFO + ConfigParams.ENDSWITH_TXT))
Config["Path"]["Save_OrgBCG"] = str(
Path(Config["Path"]["Save_OrgBCG"]) / Path(
ConfigParams.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + ConfigParams.ENDSWITH_TXT))
else: else:
return result return result
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], ConfigParams.BCG_FILTER) Config["Path"]["Input_Approximately_Align"] = str(
Path(Config["Path"]["Input_Approximately_Align"]) / Path(
Filename.APPROXIMATELY_ALIGN_INFO + Params.ENDSWITH_CSV))
Config["Path"]["Save_AlignInfo"] = str(
Path(Config["Path"]["Save_AlignInfo"]) / Path(
Filename.PRECISELY_ALIGN_INFO + Params.ENDSWITH_TXT))
Config["Path"]["Save_OrgBCG"] = str(
Path(Config["Path"]["Save_OrgBCG"]) / Path(
Filename.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + Params.ENDSWITH_TXT))
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_FILTER, Params.ENDSWITH_TXT)
if result.status: 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"]
Config["Path"]["Input_Jpeak"] = str(
Path(Config["Path"]["Input_Jpeak"]) / Path(ConfigParams.JPEAK_REVISE_CORRECTED + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
Config["Path"]["Save_BCG"] = str(
Path(Config["Path"]["Save_BCG"]) / Path(
ConfigParams.BCG_SYNC + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
Config["Path"]["Save_Jpeak"] = str(
Path(Config["Path"]["Save_Jpeak"]) / Path(
ConfigParams.JPEAK_SYNC + str(Config["InputConfig"]["BCGFreq"]) + ConfigParams.ENDSWITH_TXT))
else: else:
return result return result
result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], ConfigParams.ECG_FILTER) Config["Path"]["Input_Jpeak"] = str(
Path(Config["Path"]["Input_Jpeak"]) / Path(Filename.JPEAK_REVISE_CORRECTED + str(
Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_BCG"] = str(
Path(Config["Path"]["Save_BCG"]) / Path(
Filename.BCG_SYNC + str(Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_Jpeak"] = str(
Path(Config["Path"]["Save_Jpeak"]) / Path(
Filename.JPEAK_SYNC + str(Config["InputConfig"]["BCGFreq"]) + Params.ENDSWITH_TXT))
result = PublicFunc.examine_file(Config["Path"]["Input_ECG"], Filename.ECG_FILTER, Params.ENDSWITH_TXT)
if result.status: 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"]
Config["Path"]["Input_Rpeak"] = str(
Path(Config["Path"]["Input_Rpeak"]) / Path(ConfigParams.RPEAK_FINAL_CORRECTED + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
Config["Path"]["Save_ECG"] = str(
Path(Config["Path"]["Save_ECG"]) / Path(
ConfigParams.ECG_SYNC + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
Config["Path"]["Save_Rpeak"] = str(
Path(Config["Path"]["Save_Rpeak"]) / Path(
ConfigParams.RPEAK_SYNC + str(Config["InputConfig"]["ECGFreq"]) + ConfigParams.ENDSWITH_TXT))
else: else:
return result return result
Config["Path"]["Input_Rpeak"] = str(
Path(Config["Path"]["Input_Rpeak"]) / Path(
Filename.RPEAK_FINAL_CORRECTED + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_ECG"] = str(
Path(Config["Path"]["Save_ECG"]) / Path(
Filename.ECG_SYNC + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
Config["Path"]["Save_Rpeak"] = str(
Path(Config["Path"]["Save_Rpeak"]) / Path(
Filename.RPEAK_SYNC + str(Config["InputConfig"]["ECGFreq"]) + Params.ENDSWITH_TXT))
if ((not Path(Config["Path"]["Input_OrgBCG"]).exists()) if not Path(Config["Path"]["Input_Jpeak"]).exists():
or (not Path(Config["Path"]["Input_BCG"]).exists()) return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
or (not Path(Config["Path"]["Input_Jpeak"]).exists()) Filename.JPEAK_REVISE_CORRECTED + "" +
or (not Path(Config["Path"]["Input_ECG"]).exists()) Config["Path"]["Input_Jpeak"] +
or (not Path(Config["Path"]["Input_Rpeak"]).exists())): Constants.FAILURE_REASON["Path_Not_Exist"])
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"]) if not Path(Config["Path"]["Input_Rpeak"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
Filename.RPEAK_FINAL_CORRECTED + "" +
Config["Path"]["Input_Rpeak"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
Filename.APPROXIMATELY_ALIGN_INFO + "" +
Config["Path"]["Input_Approximately_Align"] +
Constants.FAILURE_REASON["Path_Not_Exist"])
try: 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)
@ -1536,6 +1548,7 @@ class Data:
self.BCG_early = False self.BCG_early = False
elif self.approximately_align_pos < 0: elif self.approximately_align_pos < 0:
self.BCG_early = True self.BCG_early = True
self.approximately_align_pos = - self.approximately_align_pos
else: else:
self.approximately_align_pos = 0 self.approximately_align_pos = 0
self.BCG_early = None self.BCG_early = None
@ -1858,9 +1871,6 @@ class Data:
return Result().success(info=info) return Result().success(info=info)
def save_alignInfo(self): def save_alignInfo(self):
if (not Path(Config["Path"]["Save_AlignInfo"]).parent.exists()) or (not Path(Config["Path"]["Save_AlignInfo"]).parent.is_dir()):
Path(Config["Path"]["Save_AlignInfo"]).parent.mkdir(parents=True, exist_ok=True)
try: try:
save_data = { save_data = {
"front": { "front": {
@ -1992,19 +2002,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)
@ -239,7 +240,8 @@ class MainWindow_preprocess(QMainWindow):
QApplication.processEvents() QApplication.processEvents()
# 清空画框 # 清空画框
self.ax0.clear() if self.ax0 is not None:
self.ax0.clear()
# 释放资源 # 释放资源
del self.data del self.data
@ -363,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)
@ -385,9 +387,10 @@ class MainWindow_preprocess(QMainWindow):
PublicFunc.finish_operation(self, ButtonState) PublicFunc.finish_operation(self, ButtonState)
def reset_axes(self): def reset_axes(self):
self.ax0.clear() if self.ax0 is not None:
self.ax0.grid(True) self.ax0.clear()
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER) self.ax0.grid(True)
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
class Data: class Data:
@ -398,31 +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)
if not Path(Config["Path"]["Input"]).exists(): result = PublicFunc.examine_file(Config["Path"]["Input"], signal, Params.ENDSWITH_TXT)
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON["Path_Not_Exist"])
result = PublicFunc.examine_file(Config["Path"]["Input"], signal)
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 +
@ -474,9 +474,6 @@ class Data:
return Result().success(info=Constants.PREPROCESS_FINISHED) return Result().success(info=Constants.PREPROCESS_FINISHED)
def save(self, chunk): def save(self, chunk):
if (not Path(Config["Path"]["Save"]).parent.exists()) or (not Path(Config["Path"]["Save"]).parent.is_dir()):
Path(Config["Path"]["Save"]).parent.mkdir(parents=True, exist_ok=True)
if self.processed_data is None: if self.processed_data is None:
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"]) return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])

File diff suppressed because it is too large Load Diff

View File

@ -2,23 +2,82 @@ from PySide6.QtGui import QIntValidator, QDoubleValidator
from matplotlib.ticker import FuncFormatter from matplotlib.ticker import FuncFormatter
class ConfigParams: class Filename:
# 文件命名
PATH_ORGBCG_TEXT: str = "OrgBCG_Text"
PATH_PSG_TEXT: str = "PSG_Text"
PATH_ORGBCG_ALIGNED: str = "OrgBCG_Aligned"
PATH_PSG_ALIGNED: str = "PSG_Aligned"
PATH_ORGBCG_ORIGIN: str = "OrgBCG_Origin"
PATH_PSG_ORIGIN: str = "PSG_Origin"
PATH_LABEL: str = "Label"
PATH_REVEIVE_ORIGIN: str = "Receive_Origin"
PATH_REPORT: str = "Report"
PATH_SAMPID: str = "<sampID>"
SUFFIX_FREQ: str = "采样率"
# Folder: OrgBCG_Text
ORGBCG_RAW: str = "OrgBCG_Raw_"
BCG_FILTER: str = "BCG_Filter_"
JPEAK_REVISE: str = "Jpeak_revise_"
JPEAK_REVISE_CORRECTED: str = "Jpeak_revise_corrected_"
# Folder: PSG_Text
ECG_RAW: str = "ECG II_Raw_"
THO_RAW: str = "Effort Tho_Raw_"
ABD_RAW: str = "Effort Abd_Raw_"
FLOWT_RAW: str = "Flow T_Raw_"
FLOWP_RAW: str = "Flow P_Raw_"
SNORE_RAW: str = "Snore_Raw_"
SPO2_RAW: str = "SpO2_Raw_"
FIVE_CLASS_RAW: str = "5_class_Raw_"
STARTTIME_RAW: str = "StartTime_Raw"
SA_LABEL_RAW: str = "SA Label_Raw"
ECG_FILTER: str = "ECG_Filter_"
RPEAK_FINAL: str = "Rpeak_final_"
RPEAK_FINAL_CORRECTED: str = "Rpeak_final_corrected_"
# Folder: OrgBCG_Aligned
ORGBCG_SYNC: str = "OrgBCG_Sync_"
BCG_SYNC: str = "BCG_Sync_"
# Folder: PSG_Aligned
ECG_SYNC: str = "ECG_Sync_"
THO_SYNC: str = "Effort Tho_Sync_"
ABD_SYNC: str = "Effort Abd_Sync_"
FLOWT_SYNC: str = "Flow T_Sync_"
FLOWP_SYNC: str = "Flow P_Sync_"
SNORE_SYNC: str = "Snore_Sync_"
SPO2_SYNC: str = "SpO2_Sync_"
FIVE_CLASS_SYNC: str = "5_class_Sync_"
SA_LABEL_SYNC: str = "SA Label_Sync"
JPEAK_SYNC: str = "Jpeak_Sync_"
RPEAK_SYNC: str = "Rpeak_Sync_"
# Folder: Label
APPROXIMATELY_ALIGN_INFO: str = "Approximately_Align_Info"
PRECISELY_ALIGN_INFO: str = "Precisely_Align_Info"
ARTIFACT_A: str = "Artifact_a_"
ARTIFACT_B: str = "Artifact_b_"
ARTIFACT_C: str = "Artifact_c_"
SA_LABEL_CORRECTED: str = "SA Label_corrected"
SA_LABEL_ADD: str = "SA Label_add"
RESP_QUALITY_LABEL: str = "Resp_quality_label"
THO_PEAK: str = "Tho_peak_"
SQ_LABEL_10S: str = "SQ_label_10s"
SQ_LABEL_30S: str = "SQ_label_30s"
class Params:
# 公共 # 公共
PUBLIC_CONFIG_FILE_PATH: str = "./config/Config_public.yaml" PUBLIC_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 = { PUBLIC_CONFIG_NEW_CONTENT = {
"Path": { "Path": {
"Root": "" "Root": ""
} }
} }
UTF8_ENCODING: str = "utf-8" UTF8_ENCODING: str = "utf-8"
# 目前用到这个编码的地方:
# <BCG的质量评估打标>里的保存和读取csv文件的地方注意的是读取原始数据时依然使用UTF-8
GBK_ENCODING: str = "gbk" GBK_ENCODING: str = "gbk"
ENDSWITH_TXT: str = ".txt" ENDSWITH_TXT: str = ".txt"
ENDSWITH_CSV: str = ".csv" ENDSWITH_CSV: str = ".csv"
@ -30,45 +89,6 @@ class ConfigParams:
VALIDATOR_INTEGER = QIntValidator(-2**31, 2**31 - 1) VALIDATOR_INTEGER = QIntValidator(-2**31, 2**31 - 1)
VALIDATOR_DOUBLE = QDoubleValidator(-1e100, 1e100, 10) VALIDATOR_DOUBLE = QDoubleValidator(-1e100, 1e100, 10)
# 文件命名
ORGBCG_RAW: str = "OrgBCG_Raw_"
ECG_RAW: str = "ECG II_Raw_"
THO_RAW: str = "Effort Tho_Raw_"
ABD_RAW: str = "Effort Abd_Raw_"
FLOWT_RAW: str = "Flow T_Raw_"
FLOWP_RAW: str = "Flow P_Raw_"
SNORE_RAW: str = "Snore_Raw_"
SPO2_RAW: str = "SpO2_Raw_"
FIVE_CLASS_RAW: str = "5_class_Raw_"
STARTTIME_RAW: str = "StartTime_Raw_"
SA_LABEL_RAW: str = "SA Label_Raw_"
BCG_FILTER: str = "BCG_Filter_"
ECG_FILTER: str = "ECG_Filter_"
JPEAK_REVISE: str = "Jpeak_revise_"
RPEAK_FINAL: str = "Rpeak_final_"
JPEAK_REVISE_CORRECTED: str = "Jpeak_revise_corrected_"
RPEAK_FINAL_CORRECTED: str = "Rpeak_final_corrected_"
APPROXIMATELY_ALIGN_INFO: str = "Approximately_Align_Info"
PRECISELY_ALIGN_INFO: str = "Precisely_Align_Info"
ARTIFACT_A: str = "Artifact_a"
ARTIFACT_B: str = "Artifact_b"
ARTIFACT_C: str = "Artifact_c"
BCG_SYNC: str = "BCG_Sync_"
ECG_SYNC: str = "ECG_Sync_"
JPEAK_SYNC: str = "Jpeak_Sync_"
RPEAK_SYNC: str = "Rpeak_Sync_"
ORGBCG_SYNC: str = "OrgBCG_Sync_"
THO_SYNC: str = "Effort Tho_Sync_"
ABD_SYNC: str = "Effort Abd_Sync_"
FLOWT_SYNC: str = "Flow T_Sync_"
FLOWP_SYNC: str = "Flow P_Sync_"
SNORE_SYNC: str = "Snore_Sync_"
SPO2_SYNC: str = "SpO2_Sync_"
FIVE_CLASS_SYNC: str = "5_class_Sync_"
SA_LABEL_SYNC: str = "SA Label_Sync"
SA_LABEL_CORRECTED: str = "SA Label_corrected"
SA_LABEL_ADD: str = "SA Label_add"
# 数据粗同步 # 数据粗同步
APPROXIMATELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_approximately_align.yaml" APPROXIMATELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_approximately_align.yaml"
APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT: dict = { APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
@ -195,29 +215,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,
@ -251,6 +271,44 @@ class ConfigParams:
ARTIFACT_LABEL_LABEL_TRANSPARENCY: float = 0.3 ARTIFACT_LABEL_LABEL_TRANSPARENCY: float = 0.3
ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY: str = "Z" ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY: str = "Z"
# BCG的质量标注
BCG_QUALITY_LABEL_CONFIG_FILE_PATH: str = "./config/Config_bcg_quality_label.yaml"
BCG_QUALITY_LABEL_CONFIG_NEW_CONTENT: dict = {
"InputConfig": {
"BCGFreq": 1000,
"UseFreq": 1000
}
}
BCG_QUALITY_LABEL_BTN_PREV_SHORTCUT_KEY: str = "A"
BCG_QUALITY_LABEL_BTN_NEXT_SHORTCUT_KEY: str = "D"
# 呼吸可用性及间期标注
RESP_QUALITY_LABEL_CONFIG_FILE_PATH: str = "./config/Config_resp_quality_label.yaml"
RESP_QUALITY_LABEL_CONFIG_NEW_CONTENT: dict = {
"InputConfig": {
"OrgBCGFreq": 1000,
"ThoFreq": 100,
"OrgBCGUseFreq": 1000,
"ThoUseFreq": 100
},
"Threshold": {
"Low": 0.65,
"High": 0.8
},
"FindPeaks" : {
"MinInterval": 300,
"MinHeight": 0.1
},
"Filter": {
"BandPassLow": 0.1,
"BandPassHigh": 1
}
}
RESP_QUALITY_LABEL_PREPROCESS_FC: int = 1
RESP_QUALITY_LABEL_PARTS_TIME_SEC: int = 30
RESP_QUALITY_LABEL_LABEL_TRANSPARENCY: float = 0.2
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
# 睡眠呼吸暂停事件标注 # 睡眠呼吸暂停事件标注
SA_LABEL_CONFIG_FILE_PATH: str = "./config/Config_SA_label.yaml" SA_LABEL_CONFIG_FILE_PATH: str = "./config/Config_SA_label.yaml"
SA_LABEL_CONFIG_NEW_CONTENT: dict = { SA_LABEL_CONFIG_NEW_CONTENT: dict = {
@ -281,62 +339,10 @@ class ConfigParams:
SA_LABEL_RADIOBUTTON_2_CLASS_SHORTCUT_KEY: str = "I" SA_LABEL_RADIOBUTTON_2_CLASS_SHORTCUT_KEY: str = "I"
SA_LABEL_RADIOBUTTON_3_CLASS_SHORTCUT_KEY: str = "O" SA_LABEL_RADIOBUTTON_3_CLASS_SHORTCUT_KEY: str = "O"
# 质量打标
BCG_QUALITY_LABEL_INPUT_BCG_FILENAME: str = "BCG_sync_"
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME: str = "Artifact_a"
BCG_QUALITY_LABEL_SAVE_FILENAME: str = "SQ_label_"
BCG_QUALITY_LABEL_INPUT_DEFAULT_FS: int = 1000
BCG_QUALITY_LABEL_SAVE_MODE_10S: str = "10s"
BCG_QUALITY_LABEL_SAVE_MODE_30S: str = "30s"
BCG_QUALITY_LABEL_MODE_10S_LENGTH = 10 * BCG_QUALITY_LABEL_INPUT_DEFAULT_FS
BCG_QUALITY_LABEL_MODE_30S_LENGTH = 30 * BCG_QUALITY_LABEL_INPUT_DEFAULT_FS
# 呼吸可用性及间期标注
RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME: str = "orgBcg_sync_"
RESP_QUALITY_LABEL_INPUT_THO_FILENAME: str = "Effort_Tho_sync_"
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME: str = "Artifact_a"
RESP_QUALITY_LABEL_SAVE_RESP_QUALITY_LABNEL_FILENAME: str = "Resp_quality_label"
RESP_QUALITY_LABEL_SAVE_THO_PEAK_FILENAME: str = "Tho_peak"
RESP_QUALITY_LABEL_INPUT_XINXIAO_DEFAULT_FS: int = 1000
RESP_QUALITY_LABEL_INPUT_THO_DEFAULT_FS: int = 200
RESP_QUALITY_LABEL_PARTS_TIME_SEC: int = 30
RESP_QUALITY_LABEL_PREPROCESS_FC: int = 1
RESP_QUALITY_LABEL_THRESHOLD1_DEFAULT: float = 0.65
RESP_QUALITY_LABEL_THRESHOLD2_DEFAULT: float = 0.8
RESP_QUALITY_LABEL_FINDPEAKS_MIN_INTERVAL_DEFAULT: int = 300
RESP_QUALITY_LABEL_FINDPEAKS_MIN_HEIGHT_DEFAULT: float = 0.1
RESP_QUALITY_LABEL_CUSTOM_LOW_DEFAULT: float = 0.1
RESP_QUALITY_LABEL_CUSTOM_HIGH_DEFAULT: float = 1
RESP_QUALITY_LABEL_LABEL_TRANSPARENCY: float = 0.2
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
# 睡眠呼吸暂停事件打标
# 禁止实例化 # 禁止实例化
def __new__(cls): 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:
@ -94,16 +94,18 @@ class Constants:
"Path_Not_Exist": "(路径不存在)", "Path_Not_Exist": "(路径不存在)",
"File_Not_Exist": "(数据文件不存在)", "File_Not_Exist": "(数据文件不存在)",
"File_More_Than_One": "(数据文件超过一个)", "File_More_Than_One": "(数据文件超过一个)",
"Data_Frequency_Not_In_Filename": "(无法找到文件名中的数据频率信息)",
"Suffix_Not_Correct": "(文件扩展名不正确)",
"Frequency_Not_In_Filename": "(数据频率不在文件名中)", "Frequency_Not_In_Filename": "(数据频率不在文件名中)",
"Data_Not_Exist": "(数据不存在)", "Data_Not_Exist": "(数据不存在)",
"Model_File_Not_Exist": "(模型文件不存在)", "Model_Path_Not_Exist": "(模型文件不存在)",
"Cut_Data_Length_not_Correct": "(切割数据时长度不正确)", "Cut_Data_Length_not_Correct": "(切割数据时长度不正确)",
"Align_Label_SALabel_Format_not_Correct": "映射标签时SA Label中的文件格式不正确", "Align_Label_SALabel_Format_not_Correct": "映射标签时SA Label中的文件格式不正确",
"Filename_Format_not_Correct": "(文件名格式不正确)", "Filename_Format_not_Correct": "(文件名格式不正确)",
"Method_Not_Exist": "(检测方法不存在)", "Method_Not_Exist": "(检测方法不存在)",
"Data_Length_not_Correct": "orgBcg和BCG长度不匹配", "Data_Length_not_Correct": "orgBcg和BCG长度不匹配",
"Artifact_Format_Not_Correct": "(体动长度或格式不正确)", "Artifact_Format_Not_Correct": "(体动长度或格式不正确)",
"Get_Artifact_Format_Exception": "获取体动长度或格式异常", "Data_Length_Not_Correct": "信号长度不正确",
"Open_Data_Exception": "(打开数据异常)", "Open_Data_Exception": "(打开数据异常)",
"Process_Exception": "(处理异常)", "Process_Exception": "(处理异常)",
@ -132,7 +134,9 @@ class Constants:
"Get_File_and_Freq_Excepetion": "(检查文件是否存在并获取其数据采样率异常)", "Get_File_and_Freq_Excepetion": "(检查文件是否存在并获取其数据采样率异常)",
"Update_tableWidget_Exception": "(更新表格异常)", "Update_tableWidget_Exception": "(更新表格异常)",
"Update_Info_Exception": "(更新信息异常)", "Update_Info_Exception": "(更新信息异常)",
"Get_Artifact_Format_Exception": "(获取体动长度或格式异常)",
"Label_Format_Exception": "(获取标签格式异常)", "Label_Format_Exception": "(获取标签格式异常)",
"Calculate_Peak_Exception": "(计算峰值异常)",
"res_orgBcg_Not_Exist": "切割后orgBcg不存在", "res_orgBcg_Not_Exist": "切割后orgBcg不存在",
"res_BCG_Not_Exist": "切割后BCG不存在", "res_BCG_Not_Exist": "切割后BCG不存在",
@ -240,7 +244,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 +300,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 = "正在获取文件及其采样率"
@ -324,11 +328,17 @@ class Constants:
ARTIFACT_LABEL_JUMP_ARTIFACT: str = "跳转到体动" ARTIFACT_LABEL_JUMP_ARTIFACT: str = "跳转到体动"
ARTIFACT_LABEL_RECOVER_SCALE: str = "尺度恢复" ARTIFACT_LABEL_RECOVER_SCALE: str = "尺度恢复"
ARTIFACT_LABEL_MISS_ARGS: str = "打标参数未填写" ARTIFACT_LABEL_MISS_ARGS: str = "打标参数未填写"
ARTIFACT_LABEL_OVERLAPPING: str = "当前所打标的片段存在重合,重合片段序号:" ARTIFACT_LABEL_MULTIPLE_ARTIFACT_COVER_OR_DELETE: str = "所选区域包含多种类型的体动,是否需要删除它们并使用新标注进行覆盖?所选区域中含有的体动序号:"
ARTIFACT_LABEL_MERGE: str = "当前所打标的片段距离附近片段不到2秒片段序号" ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE: str = "所选区域前2秒内有与当前标注相同类型的体动将执行合并"
ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE: str = "所选区域后2秒内有与当前标注相同类型的体动将执行合并"
ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE: str = "所选区域前后2秒内都有与当前标注相同类型的体动将执行合并"
ARTIFACT_LABEL_FRONT_TWO_SECONDS_WARNING: str = "所选区域前2秒内有与当前标注相同类型的体动仅进行提示"
ARTIFACT_LABEL_BACK_TWO_SECONDS_WARNING: str = "所选区域后2秒内有与当前标注相同类型的体动仅进行提示"
ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_WARNING: str = "所选区域前后2秒内都有与当前标注相同类型的体动仅进行提示"
ARTIFACT_LABEL_SINGLE_TYPE_NOT_EQUAL: str = "所选区域仅包含一种类型的体动,但其类型与当前标注的类型不匹配,是否需要删除它们并使用新标注覆盖?所选区域中含有的体动序号:"
ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY: str = "体动被删除" ARTIFACT_LABEL_DELETE_ARTIFACT_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 {
@ -381,6 +391,93 @@ class Constants:
background-color: #00ff00; /* 鼠标悬停时的背景颜色 */ background-color: #00ff00; /* 鼠标悬停时的背景颜色 */
}""" }"""
# BCG的质量标注
BCG_QUALITY_LABEL_COLUMN_LABEL: str = "label"
BCG_QUALITY_LABEL_COLUMN_REMARK: str = "remark"
BCG_QUALITY_LABEL_PLOT_LABEL_SIGNAL: str = "BCG"
BCG_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
BCG_QUALITY_LABEL_PLOT_LABEL_LONGEST_CONTINUOUS: str = "Longest_Continuous"
BCG_QUALITY_LABEL_10S_A: str = "a1"
BCG_QUALITY_LABEL_10S_B: str = "b1"
BCG_QUALITY_LABEL_10S_C: str = "c1"
BCG_QUALITY_LABEL_30S_A1: str = "a1"
BCG_QUALITY_LABEL_30S_A2: str = "a2"
BCG_QUALITY_LABEL_30S_B1: str = "b1"
BCG_QUALITY_LABEL_30S_B2: str = "b2"
BCG_QUALITY_LABEL_30S_C: str = "c1"
BCG_QUALITY_LABEL_TOBELABELED: str = "f1"
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART_UNLABELED: str = "前面的片段都被打标将跳转至第1段信号"
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART_UNLABELED: str = "后面的片段都被打标将跳转至最后1段信号"
BCG_QUALITY_LABEL_LABELED_FINISHED: str = "该份数据打标已全部完成"
BCG_QUALITY_LABEL_VIEWING_PART: str = "正在查看信号段"
BCG_QUALITY_LABEL_JUMP_PART: str = "跳转到片段"
BCG_QUALITY_LABEL_LABEL_ALL_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有片段标记为类型C"
BCG_QUALITY_LABEL_LABEL_ARTIFACT_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有带有体动的片段标记为类型C"
BCG_QUALITY_LABEL_LABELBTN_STYLE: str = """
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}"""
# 呼吸可用性及间期标注
RESP_QUALITY_LABEL_CALCULATING_PEAK: str = "正在计算峰值"
RESP_QUALITY_LABEL_CALCULATE_FINISHED: str = "计算完成"
RESP_QUALITY_LABEL_CALCULATE_FAILURE: str = "计算失败"
RESP_QUALITY_LABEL_PLOT_LABEL_ORGBCG: str = "BDR_Sync by filter OrgBCG_Sync"
RESP_QUALITY_LABEL_PLOT_LABEL_THO: str = "THO_Sync after preprocess"
RESP_QUALITY_LABEL_PLOT_LABEL_THO_PEAKS: str = "Tho_peak"
RESP_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
RESP_QUALITY_LABEL_SPECTRUM_BDR_TITLE: str = "Spectrum of BDR_sync by filter OrgBCG_Sync"
RESP_QUALITY_LABEL_SPECTRUM_THO_TITLE: str = "Spectrum of THO_sync after preprocess"
RESP_QUALITY_LABEL_SPECTRUM_ORGBCG_LABEL: str = "OrgBCG"
RESP_QUALITY_LABEL_SPECTRUM_BDR_LABEL: str = "BDR"
RESP_QUALITY_LABEL_SPECTRUM_THO_LABEL: str = "Tho"
RESP_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
RESP_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
RESP_QUALITY_LABEL_PREV_PART: str = "上一个片段index "
RESP_QUALITY_LABEL_NEXT_PART: str = "下一个片段index "
RESP_QUALITY_LABEL_JUMP: str = "跳转到片段index "
RESP_QUALITY_LABEL_LABEL_SUCCESSFULLY: str = "片段标注成功"
RESP_QUALITY_LABEL_LABEL_TYPE: str = "标注类型为:"
RESP_QUALITY_LABEL_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
RESP_QUALITY_LABEL_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
RESP_QUALITY_LABEL_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无新增或删除点"
RESP_QUALITY_LABEL_CUSTOM_FILTER_ARGS_ERROR: str = "OrgBCG带通滤波频率设置范围应为数字范围是0~1"
RESP_QUALITY_LABEL_AUTOLABEL_ARGS_ERROR: str = "人工标注阈值设置范围应为数字范围是0~1"
RESP_QUALITY_LABEL_CHECK_ARGS_QUESTION_CONTENT: str = "你确定要执行此操作吗,请确保参数输入正确"
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({Params.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
RESP_QUALITY_LABEL_A_QUALITY: int = 1
RESP_QUALITY_LABEL_B_QUALITY: int = 0
RESP_QUALITY_LABEL_C_QUALITY: int = -1
RESP_QUALITY_LABEL_KEY_VALUE = {
1: "Good",
0: "Bad",
-1: "None"
}
RESP_QUALITY_LABEL_FIGTOOLBAR_SPECTRUM_STYLESHEET: str = """
QToolBar {
border: 1px;
spacing: 2px; /* 设置工具栏按钮之间的间距 */
}
QToolButton {
height: 20px; /* 设置工具栏按钮的高度 */
width: 20px; /* 设置工具栏按钮的宽度 */
font-size: 8px; /* 设置按钮文字大小 */
}
QToolButton::menu-button {
width: 0px; /* 隐藏下拉菜单按钮 */
}
"""
# 睡眠呼吸暂停事件标注 # 睡眠呼吸暂停事件标注
SA_LABEL_JUMP: str = "跳转到事件" SA_LABEL_JUMP: str = "跳转到事件"
SA_LABEL_VIEWING_FIRST: str = "你正在查看第1个事件" SA_LABEL_VIEWING_FIRST: str = "你正在查看第1个事件"
@ -398,133 +495,6 @@ class Constants:
SA_LABEL_LENGTH_LESS_THEN_10S: str = "当前标注的事件的持续时间小于10秒" SA_LABEL_LENGTH_LESS_THEN_10S: str = "当前标注的事件的持续时间小于10秒"
SA_LABEL_WRONG_ARGS: str = "起始时间和终止时间输入错误" SA_LABEL_WRONG_ARGS: str = "起始时间和终止时间输入错误"
# 质量打标
BCG_QUALITY_LABEL_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.BCG_QUALITY_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<BCG的质量标注>"
BCG_QUALITY_LABEL_FILES_FOUND: str = f"找到{ConfigParams.BCG_QUALITY_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT}"
BCG_QUALITY_LABEL_HISTORICAL_SAVE_FOUND: str = f"找到历史存档文件{ConfigParams.BCG_QUALITY_LABEL_SAVE_FILENAME}{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_10S}{ConfigParams.ENDSWITH_CSV}{ConfigParams.BCG_QUALITY_LABEL_SAVE_FILENAME}{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_30S}{ConfigParams.ENDSWITH_CSV},已成功读取"
BCG_QUALITY_LABEL_MODE_UNSELECTED: str = "显示模式未选择"
BCG_QUALITY_LABEL_INPUT_SIGNAL_FAILURE: str = "导入信号失败,请检查信号长度"
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_FORMAT: str = "导入体动失败,请检查体动标签格式"
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_LENGTH: str = "导入体动失败请检查体动长度是否为4的倍数"
BCG_QUALITY_LABEL_RUNNING: str = "开始执行任务<BCG的质量评估标注>"
BCG_QUALITY_LABEL_10S_MODE: str = f"{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_10S}_MODE"
BCG_QUALITY_LABEL_30S_MODE: str = f"{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_30S}_MODE"
BCG_QUALITY_LABEL_COLUMN_LABEL: str = "label"
BCG_QUALITY_LABEL_COLUMN_REMARK: str = "remark"
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART_UNLABELED: str = "前面的片段都被打标将跳转至第1段信号"
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART_UNLABELED: str = "后面的片段都被打标将跳转至最后1段信号"
BCG_QUALITY_LABEL_LABELED_FINISHED: str = "该份数据打标已全部完成"
BCG_QUALITY_LABEL_VIEWING_PART: str = "正在查看信号段"
BCG_QUALITY_LABEL_JUMP_PART: str = "跳转到片段"
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_HIGHLIGHT_LONGEST_CONTINUOUS: str = "点击了<高亮最长连续>"
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_DISPLAY_AFTERFILTER: str = "点击了<去除工频噪声>"
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_EXAMINE_TOBOLABELED: str = "点击了<仅查未标片段>"
BCG_QUALITY_LABEL_LABEL_ALL_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有片段标记为类型C"
BCG_QUALITY_LABEL_LABEL_ALL_TO_TYPE_C: str = "已将所有片段标记为类型C"
BCG_QUALITY_LABEL_LABEL_ARTIFACT_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有带有体动的片段标记为类型C"
BCG_QUALITY_LABEL_LABEL_ARTIFACT_TO_TYPE_C: str = "已将所有带有体动的片段标记为类型C"
BCG_QUALITY_LABEL_PLOT_LABEL_SIGNAL: str = "BCG"
BCG_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
BCG_QUALITY_LABEL_PLOT_LABEL_LONGEST_CONTINUOUS: str = "Longest_Continuous"
BCG_QUALITY_LABEL_10S_A: str = "a"
BCG_QUALITY_LABEL_10S_B: str = "b"
BCG_QUALITY_LABEL_10S_C: str = "c"
BCG_QUALITY_LABEL_10S_A_LIST: str = "label_a"
BCG_QUALITY_LABEL_10S_B_LIST: str = "label_b"
BCG_QUALITY_LABEL_10S_C_LIST: str = "label_c"
BCG_QUALITY_LABEL_30S_A1: str = "a"
BCG_QUALITY_LABEL_30S_A2: str = "b"
BCG_QUALITY_LABEL_30S_B1: str = "c"
BCG_QUALITY_LABEL_30S_B2: str = "d"
BCG_QUALITY_LABEL_30S_C: str = "e"
BCG_QUALITY_LABEL_30S_A1_LIST: str = "label_a1"
BCG_QUALITY_LABEL_30S_A2_LIST: str = "label_a2"
BCG_QUALITY_LABEL_30S_B1_LIST: str = "label_b1"
BCG_QUALITY_LABEL_30S_B2_LIST: str = "label_b2"
BCG_QUALITY_LABEL_30S_C_LIST: str = "label_c"
BCG_QUALITY_LABEL_tobeLabeled: str = "f"
BCG_QUALITY_LABEL_tobeLabeled_LIST: str = "label_tobeLabeled"
BCG_QUALITY_LABEL_LABELBTN_STYLE: str = """
QPushButton {
background-color: orange; /* 设置背景颜色 */
padding: 10px; /* 设置内边距 */
border: 2px solid darkblue; /* 设置边框 */
border-radius: 10px; /* 设置圆角 */
}
QPushButton:hover {
background-color: yellow; /* 鼠标悬停时的背景颜色 */
}"""
# 呼吸可用性及间期标注
RESP_QUALITY_LABEL_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.RESP_QUALITY_LABEL_INPUT_THO_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<呼吸可用性及间期标注>"
RESP_QUALITY_LABEL_FILES_FOUND: str = f"找到{ConfigParams.RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.RESP_QUALITY_LABEL_INPUT_THO_FILENAME}{ConfigParams.ENDSWITH_TXT}{ConfigParams.RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT}"
RESP_QUALITY_LABEL_HISTORICAL_SAVE1_FOUND: str = f"找到历史存档文件{ConfigParams.RESP_QUALITY_LABEL_SAVE_RESP_QUALITY_LABNEL_FILENAME}{ConfigParams.ENDSWITH_TXT},已成功读取"
RESP_QUALITY_LABEL_HISTORICAL_SAVE2_FOUND: str = f"找到历史存档文件{ConfigParams.RESP_QUALITY_LABEL_SAVE_THO_PEAK_FILENAME}{ConfigParams.ENDSWITH_TXT},已成功读取"
RESP_QUALITY_LABEL_INPUT_SIGNAL_FAILURE: str = "导入信号失败,请检查信号长度"
RESP_QUALITY_LABEL_INPUT_SUCCESSFULLY: str = "导入数据成功"
RESP_QUALITY_LABEL_PREPROCESS_SUCCESSFULLY: str = "导入数据成功"
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_FORMAT: str = "导入体动失败,请检查体动标签格式"
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_LENGTH: str = "导入体动失败请检查体动长度是否为4的倍数"
RESP_QUALITY_LABEL_RUNNING: str = "开始执行任务<呼吸可用性及间期标注>"
RESP_QUALITY_LABEL_PLOT_LABEL_ORGBCG: str = "BDR_sync by filter orgBcg_sync"
RESP_QUALITY_LABEL_PLOT_LABEL_THO: str = "THO_sync after preprocess"
RESP_QUALITY_LABEL_PLOT_LABEL_THO_PEAKS: str = "THO_peak"
RESP_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
RESP_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
RESP_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({ConfigParams.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
RESP_QUALITY_LABEL_CUSTOM_NAVIGATIONTOOLBAR_WIDGET_NAME: str = "MainWindow"
RESP_QUALITY_LABEL_BUTTON_PRESS_EVENT: str = "button_press_event"
RESP_QUALITY_LABEL_BUTTON_RELEASE_EVENT: str = "button_release_event"
RESP_QUALITY_LABEL_MOTION_NOTIFY_EVENT: str = "motion_notify_event"
RESP_QUALITY_LABEL_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
RESP_QUALITY_LABEL_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
RESP_QUALITY_LABEL_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无新增或删除点"
RESP_QUALITY_LABEL_SAVE_PEAKS_SUCCESSFULLY: str = "保存峰值成功"
RESP_QUALITY_LABEL_DATA_NOT_FOUND: str = "数据未导入"
RESP_QUALITY_LABEL_LABEL_SUCCESSFULLY: str = "片段标注并保存成功"
RESP_QUALITY_LABEL_RESET_SUCCESSFULLY: str = "片段重置并保存成功"
RESP_QUALITY_LABEL_PLOT_LABEL_VLINE: str = "vline"
RESP_QUALITY_LABEL_PLOT_LABEL_HLINE: str = "hline"
RESP_QUALITY_LABEL_A_QUALITY: int = 1
RESP_QUALITY_LABEL_B_QUALITY: int = 0
RESP_QUALITY_LABEL_C_QUALITY: int = -1
RESP_QUALITY_LABEL_LABELED: str = "已标注"
RESP_QUALITY_LABEL_TOBELABELED: str = "未标注"
RESP_QUALITY_LABEL_SPECTRUM_BDR_TITLE: str = "Spectrum of BDR_sync by filter orgBcg_sync"
RESP_QUALITY_LABEL_SPECTRUM_THO_TITLE: str = "Spectrum of THO_sync after preprocess"
RESP_QUALITY_LABEL_SPECTRUM_ORGBCG_LABEL: str = "orgBcg"
RESP_QUALITY_LABEL_SPECTRUM_BDR_LABEL: str = "BDR"
RESP_QUALITY_LABEL_SPECTRUM_THO_LABEL: str = "THO"
RESP_QUALITY_LABEL_CUSTOM_FILTER_ARGS_ERROR: str = "orgBcg带通滤波频率设置范围应为数字范围是0~1"
RESP_QUALITY_LABEL_AUTOLABEL_ARGS_ERROR: str = "人工标注阈值设置范围应为数字范围是0~1"
RESP_QUALITY_LABEL_CHECK_ARGS_QUESTION_CONTENT: str = "你确定要执行此操作吗,请确保参数输入正确"
RESP_QUALITY_LABEL_KEY_VALUE = {
1: "Good",
0: "Bad",
-1: "None"
}
# 禁止实例化 # 禁止实例化
def __new__(cls): def __new__(cls):
raise TypeError("Constants class cannot be instantiated") raise TypeError("Constants class cannot be instantiated")

View File

@ -177,7 +177,7 @@ class PublicFunc:
QApplication.processEvents() QApplication.processEvents()
@staticmethod @staticmethod
def examine_file(path_str, filename): def examine_file(path_str, filename, suffix):
temp_path = list( temp_path = list(
Path(path_str).glob(f"{filename}*")) Path(path_str).glob(f"{filename}*"))
if len(temp_path) == 0: if len(temp_path) == 0:
@ -201,8 +201,24 @@ class PublicFunc:
info=Constants.INPUT_FAILURE + "\n" + info=Constants.INPUT_FAILURE + "\n" +
filename + "" + filename + "" +
Constants.FAILURE_REASON["Data_Frequency_Not_In_Filename"]) Constants.FAILURE_REASON["Data_Frequency_Not_In_Filename"])
if Path(path).suffix != suffix:
return Result().failure(
info=Constants.INPUT_FAILURE + "\n" +
filename + "" +
Constants.FAILURE_REASON["Suffix_Not_Correct"])
data = { data = {
"path": str(path), "path": str(path),
"freq": int(freq) "freq": int(freq)
} }
return Result().success(data=data) return Result().success(data=data)
@staticmethod
def examine_artifact(artifact):
# 检查体动标签正确性,长度
if len(artifact) % 4 != 0:
return Result().failure(info=Constants.INPUT_FAILURE +
Constants.FAILURE_REASON["Artifact_Format_Not_Correct"])
for i in range(0, len(artifact), 4):
unit_data = artifact[i:i + 4]
if len(unit_data) < 4:
break

View File

@ -389,14 +389,6 @@ class Ui_MainWindow_artifact_label(object):
self.verticalLayout_2.addItem(self.verticalSpacer_3) self.verticalLayout_2.addItem(self.verticalSpacer_3)
self.pushButton_save = QPushButton(self.groupBox_left)
self.pushButton_save.setObjectName(u"pushButton_save")
sizePolicy.setHeightForWidth(self.pushButton_save.sizePolicy().hasHeightForWidth())
self.pushButton_save.setSizePolicy(sizePolicy)
self.pushButton_save.setFont(font1)
self.verticalLayout_2.addWidget(self.pushButton_save)
self.groupBox_4 = QGroupBox(self.groupBox_left) self.groupBox_4 = QGroupBox(self.groupBox_left)
self.groupBox_4.setObjectName(u"groupBox_4") self.groupBox_4.setObjectName(u"groupBox_4")
self.verticalLayout_6 = QVBoxLayout(self.groupBox_4) self.verticalLayout_6 = QVBoxLayout(self.groupBox_4)
@ -415,7 +407,6 @@ class Ui_MainWindow_artifact_label(object):
self.verticalLayout_2.setStretch(3, 1) self.verticalLayout_2.setStretch(3, 1)
self.verticalLayout_2.setStretch(4, 6) self.verticalLayout_2.setStretch(4, 6)
self.verticalLayout_2.setStretch(5, 1) self.verticalLayout_2.setStretch(5, 1)
self.verticalLayout_2.setStretch(6, 1)
self.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1) self.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1)
@ -717,7 +708,6 @@ class Ui_MainWindow_artifact_label(object):
self.label_7.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u79fb\u52a8\u8ddd\u79bb", None)) self.label_7.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u79fb\u52a8\u8ddd\u79bb", None))
self.label_6.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u6700\u5927\u8303\u56f4", None)) self.label_6.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u6700\u5927\u8303\u56f4", None))
self.label_8.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u79fb\u52a8\u95f4\u9694(ms)", None)) self.label_8.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u79fb\u52a8\u95f4\u9694(ms)", None))
self.pushButton_save.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u5bfc\u51fa\u6807\u7b7e", None))
self.groupBox_4.setTitle(QCoreApplication.translate("MainWindow_artifact_label", u"\u65e5\u5fd7", None)) self.groupBox_4.setTitle(QCoreApplication.translate("MainWindow_artifact_label", u"\u65e5\u5fd7", None))
self.groupBox_right.setTitle(QCoreApplication.translate("MainWindow_artifact_label", u"\u6807\u6ce8\u64cd\u4f5c\u548c\u4fe1\u606f", None)) self.groupBox_right.setTitle(QCoreApplication.translate("MainWindow_artifact_label", u"\u6807\u6ce8\u64cd\u4f5c\u548c\u4fe1\u606f", None))
self.pushButton_type_1.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u5267\u70c8\u4f53\u52a8", None)) self.pushButton_type_1.setText(QCoreApplication.translate("MainWindow_artifact_label", u"\u5267\u70c8\u4f53\u52a8", None))

View File

@ -42,7 +42,7 @@
<property name="title"> <property name="title">
<string>体动标注</string> <string>体动标注</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,1,3,1,6,1,1,0"> <layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,1,3,1,6,1,0">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
@ -676,24 +676,6 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QPushButton" name="pushButton_save">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>导出标签</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBox_4"> <widget class="QGroupBox" name="groupBox_4">
<property name="title"> <property name="title">

View File

@ -0,0 +1,537 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'MainWindow_bcg_quality_label.ui'
##
## Created by: Qt User Interface Compiler version 6.8.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QCheckBox, QGridLayout, QGroupBox,
QHBoxLayout, QHeaderView, QLabel, QLineEdit,
QMainWindow, QPushButton, QSizePolicy, QSpacerItem,
QStatusBar, QTableWidget, QTableWidgetItem, QTextBrowser,
QVBoxLayout, QWidget)
class Ui_MainWindow_bcg_quality_label(object):
def setupUi(self, MainWindow_bcg_quality_label):
if not MainWindow_bcg_quality_label.objectName():
MainWindow_bcg_quality_label.setObjectName(u"MainWindow_bcg_quality_label")
MainWindow_bcg_quality_label.resize(1920, 1080)
self.centralwidget = QWidget(MainWindow_bcg_quality_label)
self.centralwidget.setObjectName(u"centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.groupBox_canvas = QGroupBox(self.centralwidget)
self.groupBox_canvas.setObjectName(u"groupBox_canvas")
font = QFont()
font.setPointSize(10)
self.groupBox_canvas.setFont(font)
self.verticalLayout = QVBoxLayout(self.groupBox_canvas)
self.verticalLayout.setObjectName(u"verticalLayout")
self.verticalLayout_canvas = QVBoxLayout()
self.verticalLayout_canvas.setObjectName(u"verticalLayout_canvas")
self.verticalLayout.addLayout(self.verticalLayout_canvas)
self.gridLayout.addWidget(self.groupBox_canvas, 0, 1, 1, 1)
self.groupBox_left = QGroupBox(self.centralwidget)
self.groupBox_left.setObjectName(u"groupBox_left")
self.groupBox_left.setFont(font)
self.verticalLayout_2 = QVBoxLayout(self.groupBox_left)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.pushButton_input_setting = QPushButton(self.groupBox_left)
self.pushButton_input_setting.setObjectName(u"pushButton_input_setting")
sizePolicy = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_input_setting.sizePolicy().hasHeightForWidth())
self.pushButton_input_setting.setSizePolicy(sizePolicy)
font1 = QFont()
font1.setPointSize(12)
self.pushButton_input_setting.setFont(font1)
self.horizontalLayout.addWidget(self.pushButton_input_setting)
self.pushButton_input = QPushButton(self.groupBox_left)
self.pushButton_input.setObjectName(u"pushButton_input")
sizePolicy.setHeightForWidth(self.pushButton_input.sizePolicy().hasHeightForWidth())
self.pushButton_input.setSizePolicy(sizePolicy)
self.pushButton_input.setFont(font1)
self.horizontalLayout.addWidget(self.pushButton_input)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_2.addItem(self.verticalSpacer)
self.groupBox_status = QGroupBox(self.groupBox_left)
self.groupBox_status.setObjectName(u"groupBox_status")
self.gridLayout_3 = QGridLayout(self.groupBox_status)
self.gridLayout_3.setObjectName(u"gridLayout_3")
self.label_5 = QLabel(self.groupBox_status)
self.label_5.setObjectName(u"label_5")
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
sizePolicy1.setHorizontalStretch(0)
sizePolicy1.setVerticalStretch(0)
sizePolicy1.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth())
self.label_5.setSizePolicy(sizePolicy1)
self.label_5.setFont(font1)
self.gridLayout_3.addWidget(self.label_5, 0, 0, 1, 1)
self.label_6 = QLabel(self.groupBox_status)
self.label_6.setObjectName(u"label_6")
sizePolicy1.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth())
self.label_6.setSizePolicy(sizePolicy1)
self.label_6.setFont(font1)
self.gridLayout_3.addWidget(self.label_6, 1, 0, 1, 1)
self.label_12 = QLabel(self.groupBox_status)
self.label_12.setObjectName(u"label_12")
sizePolicy1.setHeightForWidth(self.label_12.sizePolicy().hasHeightForWidth())
self.label_12.setSizePolicy(sizePolicy1)
self.label_12.setFont(font1)
self.gridLayout_3.addWidget(self.label_12, 2, 0, 1, 1)
self.label_13 = QLabel(self.groupBox_status)
self.label_13.setObjectName(u"label_13")
sizePolicy1.setHeightForWidth(self.label_13.sizePolicy().hasHeightForWidth())
self.label_13.setSizePolicy(sizePolicy1)
self.label_13.setFont(font1)
self.gridLayout_3.addWidget(self.label_13, 3, 0, 1, 1)
self.lineEdit_artifact_time_percentage = QLineEdit(self.groupBox_status)
self.lineEdit_artifact_time_percentage.setObjectName(u"lineEdit_artifact_time_percentage")
self.lineEdit_artifact_time_percentage.setEnabled(False)
self.lineEdit_artifact_time_percentage.setFont(font1)
self.gridLayout_3.addWidget(self.lineEdit_artifact_time_percentage, 3, 1, 1, 1)
self.lineEdit_longest_continuous_time = QLineEdit(self.groupBox_status)
self.lineEdit_longest_continuous_time.setObjectName(u"lineEdit_longest_continuous_time")
self.lineEdit_longest_continuous_time.setEnabled(False)
self.lineEdit_longest_continuous_time.setFont(font1)
self.gridLayout_3.addWidget(self.lineEdit_longest_continuous_time, 2, 1, 1, 1)
self.lineEdit_data_part_num = QLineEdit(self.groupBox_status)
self.lineEdit_data_part_num.setObjectName(u"lineEdit_data_part_num")
self.lineEdit_data_part_num.setEnabled(False)
self.lineEdit_data_part_num.setFont(font1)
self.gridLayout_3.addWidget(self.lineEdit_data_part_num, 1, 1, 1, 1)
self.lineEdit_current_part_time = QLineEdit(self.groupBox_status)
self.lineEdit_current_part_time.setObjectName(u"lineEdit_current_part_time")
self.lineEdit_current_part_time.setEnabled(False)
self.lineEdit_current_part_time.setFont(font1)
self.gridLayout_3.addWidget(self.lineEdit_current_part_time, 0, 1, 1, 1)
self.verticalLayout_2.addWidget(self.groupBox_status)
self.verticalSpacer_5 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_2.addItem(self.verticalSpacer_5)
self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.groupBox_artifact_type = QGroupBox(self.groupBox_left)
self.groupBox_artifact_type.setObjectName(u"groupBox_artifact_type")
self.verticalLayout_3 = QVBoxLayout(self.groupBox_artifact_type)
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
self.checkBox_allin = QCheckBox(self.groupBox_artifact_type)
self.checkBox_allin.setObjectName(u"checkBox_allin")
font2 = QFont()
font2.setPointSize(20)
self.checkBox_allin.setFont(font2)
self.checkBox_allin.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_allin)
self.checkBox_type1 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type1.setObjectName(u"checkBox_type1")
self.checkBox_type1.setFont(font1)
self.checkBox_type1.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type1)
self.checkBox_type2 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type2.setObjectName(u"checkBox_type2")
self.checkBox_type2.setFont(font1)
self.checkBox_type2.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type2)
self.checkBox_type3 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type3.setObjectName(u"checkBox_type3")
self.checkBox_type3.setFont(font1)
self.checkBox_type3.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type3)
self.checkBox_type4 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type4.setObjectName(u"checkBox_type4")
self.checkBox_type4.setFont(font1)
self.checkBox_type4.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type4)
self.checkBox_type5 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type5.setObjectName(u"checkBox_type5")
self.checkBox_type5.setFont(font1)
self.checkBox_type5.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type5)
self.horizontalLayout_2.addWidget(self.groupBox_artifact_type)
self.groupBox_function = QGroupBox(self.groupBox_left)
self.groupBox_function.setObjectName(u"groupBox_function")
self.gridLayout_13 = QGridLayout(self.groupBox_function)
self.gridLayout_13.setObjectName(u"gridLayout_13")
self.pushButton_invalid_signal_label = QPushButton(self.groupBox_function)
self.pushButton_invalid_signal_label.setObjectName(u"pushButton_invalid_signal_label")
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
sizePolicy2.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0)
sizePolicy2.setHeightForWidth(self.pushButton_invalid_signal_label.sizePolicy().hasHeightForWidth())
self.pushButton_invalid_signal_label.setSizePolicy(sizePolicy2)
self.pushButton_invalid_signal_label.setFont(font1)
self.gridLayout_13.addWidget(self.pushButton_invalid_signal_label, 0, 0, 1, 1)
self.pushButton_Ctype_signal_label = QPushButton(self.groupBox_function)
self.pushButton_Ctype_signal_label.setObjectName(u"pushButton_Ctype_signal_label")
sizePolicy2.setHeightForWidth(self.pushButton_Ctype_signal_label.sizePolicy().hasHeightForWidth())
self.pushButton_Ctype_signal_label.setSizePolicy(sizePolicy2)
self.pushButton_Ctype_signal_label.setFont(font1)
self.gridLayout_13.addWidget(self.pushButton_Ctype_signal_label, 1, 0, 1, 1)
self.horizontalLayout_2.addWidget(self.groupBox_function)
self.horizontalLayout_2.setStretch(0, 2)
self.horizontalLayout_2.setStretch(1, 1)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
self.verticalSpacer_4 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_2.addItem(self.verticalSpacer_4)
self.groupBox_operation = QGroupBox(self.groupBox_left)
self.groupBox_operation.setObjectName(u"groupBox_operation")
self.gridLayout_7 = QGridLayout(self.groupBox_operation)
self.gridLayout_7.setObjectName(u"gridLayout_7")
self.pushButton_prev = QPushButton(self.groupBox_operation)
self.pushButton_prev.setObjectName(u"pushButton_prev")
sizePolicy2.setHeightForWidth(self.pushButton_prev.sizePolicy().hasHeightForWidth())
self.pushButton_prev.setSizePolicy(sizePolicy2)
self.pushButton_prev.setFont(font1)
self.gridLayout_7.addWidget(self.pushButton_prev, 4, 0, 1, 1)
self.checkBox_examine_tobeLabeled = QCheckBox(self.groupBox_operation)
self.checkBox_examine_tobeLabeled.setObjectName(u"checkBox_examine_tobeLabeled")
self.checkBox_examine_tobeLabeled.setFont(font1)
self.gridLayout_7.addWidget(self.checkBox_examine_tobeLabeled, 1, 0, 1, 1)
self.checkBox_highlight_longest_continuous = QCheckBox(self.groupBox_operation)
self.checkBox_highlight_longest_continuous.setObjectName(u"checkBox_highlight_longest_continuous")
self.checkBox_highlight_longest_continuous.setFont(font1)
self.gridLayout_7.addWidget(self.checkBox_highlight_longest_continuous, 0, 0, 1, 1)
self.pushButton_next = QPushButton(self.groupBox_operation)
self.pushButton_next.setObjectName(u"pushButton_next")
sizePolicy2.setHeightForWidth(self.pushButton_next.sizePolicy().hasHeightForWidth())
self.pushButton_next.setSizePolicy(sizePolicy2)
self.pushButton_next.setFont(font1)
self.gridLayout_7.addWidget(self.pushButton_next, 4, 1, 1, 1)
self.label = QLabel(self.groupBox_operation)
self.label.setObjectName(u"label")
self.label.setFont(font1)
self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.gridLayout_7.addWidget(self.label, 2, 0, 1, 1)
self.checkBox_display_afterfilter = QCheckBox(self.groupBox_operation)
self.checkBox_display_afterfilter.setObjectName(u"checkBox_display_afterfilter")
self.checkBox_display_afterfilter.setFont(font1)
self.gridLayout_7.addWidget(self.checkBox_display_afterfilter, 0, 1, 1, 1)
self.lineEdit_remark = QLineEdit(self.groupBox_operation)
self.lineEdit_remark.setObjectName(u"lineEdit_remark")
self.lineEdit_remark.setEnabled(True)
self.lineEdit_remark.setFont(font1)
self.gridLayout_7.addWidget(self.lineEdit_remark, 2, 1, 1, 1)
self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.gridLayout_7.addItem(self.verticalSpacer_2, 3, 0, 1, 2)
self.gridLayout_7.setRowStretch(0, 1)
self.gridLayout_7.setRowStretch(1, 1)
self.gridLayout_7.setRowStretch(2, 1)
self.gridLayout_7.setRowStretch(3, 1)
self.gridLayout_7.setRowStretch(4, 3)
self.gridLayout_7.setColumnStretch(0, 1)
self.gridLayout_7.setColumnStretch(1, 1)
self.verticalLayout_2.addWidget(self.groupBox_operation)
self.verticalSpacer_3 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_2.addItem(self.verticalSpacer_3)
self.groupBox_4 = QGroupBox(self.groupBox_left)
self.groupBox_4.setObjectName(u"groupBox_4")
self.verticalLayout_6 = QVBoxLayout(self.groupBox_4)
self.verticalLayout_6.setObjectName(u"verticalLayout_6")
self.textBrowser_info = QTextBrowser(self.groupBox_4)
self.textBrowser_info.setObjectName(u"textBrowser_info")
self.verticalLayout_6.addWidget(self.textBrowser_info)
self.verticalLayout_2.addWidget(self.groupBox_4)
self.verticalLayout_2.setStretch(0, 2)
self.verticalLayout_2.setStretch(1, 1)
self.verticalLayout_2.setStretch(2, 4)
self.verticalLayout_2.setStretch(3, 1)
self.verticalLayout_2.setStretch(4, 6)
self.verticalLayout_2.setStretch(5, 1)
self.verticalLayout_2.setStretch(6, 6)
self.verticalLayout_2.setStretch(7, 1)
self.verticalLayout_2.setStretch(8, 5)
self.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1)
self.groupBox_right = QGroupBox(self.centralwidget)
self.groupBox_right.setObjectName(u"groupBox_right")
self.groupBox_right.setFont(font)
self.gridLayout_4 = QGridLayout(self.groupBox_right)
self.gridLayout_4.setObjectName(u"gridLayout_4")
self.verticalSpacer_9 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.gridLayout_4.addItem(self.verticalSpacer_9, 7, 0, 1, 2)
self.verticalSpacer_7 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.gridLayout_4.addItem(self.verticalSpacer_7, 3, 0, 1, 2)
self.pushButton_b1 = QPushButton(self.groupBox_right)
self.pushButton_b1.setObjectName(u"pushButton_b1")
sizePolicy2.setHeightForWidth(self.pushButton_b1.sizePolicy().hasHeightForWidth())
self.pushButton_b1.setSizePolicy(sizePolicy2)
font3 = QFont()
font3.setPointSize(24)
self.pushButton_b1.setFont(font3)
self.gridLayout_4.addWidget(self.pushButton_b1, 4, 0, 1, 1)
self.tableWidget_c = QTableWidget(self.groupBox_right)
if (self.tableWidget_c.columnCount() < 1):
self.tableWidget_c.setColumnCount(1)
self.tableWidget_c.setObjectName(u"tableWidget_c")
self.tableWidget_c.setFont(font1)
self.tableWidget_c.setColumnCount(1)
self.gridLayout_4.addWidget(self.tableWidget_c, 8, 1, 1, 1)
self.tableWidget_a1 = QTableWidget(self.groupBox_right)
if (self.tableWidget_a1.columnCount() < 1):
self.tableWidget_a1.setColumnCount(1)
self.tableWidget_a1.setObjectName(u"tableWidget_a1")
self.tableWidget_a1.setFont(font1)
self.tableWidget_a1.setColumnCount(1)
self.tableWidget_a1.horizontalHeader().setMinimumSectionSize(33)
self.tableWidget_a1.horizontalHeader().setDefaultSectionSize(75)
self.tableWidget_a1.verticalHeader().setMinimumSectionSize(32)
self.gridLayout_4.addWidget(self.tableWidget_a1, 0, 1, 1, 1)
self.pushButton_b2 = QPushButton(self.groupBox_right)
self.pushButton_b2.setObjectName(u"pushButton_b2")
sizePolicy2.setHeightForWidth(self.pushButton_b2.sizePolicy().hasHeightForWidth())
self.pushButton_b2.setSizePolicy(sizePolicy2)
self.pushButton_b2.setFont(font3)
self.gridLayout_4.addWidget(self.pushButton_b2, 6, 0, 1, 1)
self.pushButton_f = QPushButton(self.groupBox_right)
self.pushButton_f.setObjectName(u"pushButton_f")
sizePolicy2.setHeightForWidth(self.pushButton_f.sizePolicy().hasHeightForWidth())
self.pushButton_f.setSizePolicy(sizePolicy2)
self.pushButton_f.setFont(font3)
self.gridLayout_4.addWidget(self.pushButton_f, 10, 0, 1, 1)
self.tableWidget_f = QTableWidget(self.groupBox_right)
if (self.tableWidget_f.columnCount() < 1):
self.tableWidget_f.setColumnCount(1)
self.tableWidget_f.setObjectName(u"tableWidget_f")
self.tableWidget_f.setFont(font1)
self.tableWidget_f.setColumnCount(1)
self.gridLayout_4.addWidget(self.tableWidget_f, 10, 1, 1, 1)
self.pushButton_a2 = QPushButton(self.groupBox_right)
self.pushButton_a2.setObjectName(u"pushButton_a2")
sizePolicy2.setHeightForWidth(self.pushButton_a2.sizePolicy().hasHeightForWidth())
self.pushButton_a2.setSizePolicy(sizePolicy2)
self.pushButton_a2.setFont(font3)
self.gridLayout_4.addWidget(self.pushButton_a2, 2, 0, 1, 1)
self.verticalSpacer_6 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.gridLayout_4.addItem(self.verticalSpacer_6, 1, 0, 1, 2)
self.tableWidget_b1 = QTableWidget(self.groupBox_right)
if (self.tableWidget_b1.columnCount() < 1):
self.tableWidget_b1.setColumnCount(1)
self.tableWidget_b1.setObjectName(u"tableWidget_b1")
self.tableWidget_b1.setFont(font1)
self.tableWidget_b1.setColumnCount(1)
self.gridLayout_4.addWidget(self.tableWidget_b1, 4, 1, 1, 1)
self.pushButton_a1 = QPushButton(self.groupBox_right)
self.pushButton_a1.setObjectName(u"pushButton_a1")
sizePolicy2.setHeightForWidth(self.pushButton_a1.sizePolicy().hasHeightForWidth())
self.pushButton_a1.setSizePolicy(sizePolicy2)
self.pushButton_a1.setFont(font3)
self.gridLayout_4.addWidget(self.pushButton_a1, 0, 0, 1, 1)
self.tableWidget_b2 = QTableWidget(self.groupBox_right)
if (self.tableWidget_b2.columnCount() < 1):
self.tableWidget_b2.setColumnCount(1)
self.tableWidget_b2.setObjectName(u"tableWidget_b2")
self.tableWidget_b2.setFont(font1)
self.tableWidget_b2.setColumnCount(1)
self.gridLayout_4.addWidget(self.tableWidget_b2, 6, 1, 1, 1)
self.tableWidget_a2 = QTableWidget(self.groupBox_right)
if (self.tableWidget_a2.columnCount() < 1):
self.tableWidget_a2.setColumnCount(1)
self.tableWidget_a2.setObjectName(u"tableWidget_a2")
self.tableWidget_a2.setFont(font1)
self.tableWidget_a2.setColumnCount(1)
self.gridLayout_4.addWidget(self.tableWidget_a2, 2, 1, 1, 1)
self.verticalSpacer_8 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.gridLayout_4.addItem(self.verticalSpacer_8, 5, 0, 1, 2)
self.pushButton_c = QPushButton(self.groupBox_right)
self.pushButton_c.setObjectName(u"pushButton_c")
sizePolicy2.setHeightForWidth(self.pushButton_c.sizePolicy().hasHeightForWidth())
self.pushButton_c.setSizePolicy(sizePolicy2)
self.pushButton_c.setFont(font3)
self.gridLayout_4.addWidget(self.pushButton_c, 8, 0, 1, 1)
self.verticalSpacer_10 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.gridLayout_4.addItem(self.verticalSpacer_10, 9, 0, 1, 2)
self.gridLayout_4.setRowStretch(0, 5)
self.gridLayout_4.setRowStretch(1, 1)
self.gridLayout_4.setRowStretch(2, 5)
self.gridLayout_4.setRowStretch(3, 1)
self.gridLayout_4.setRowStretch(4, 5)
self.gridLayout_4.setRowStretch(5, 1)
self.gridLayout_4.setRowStretch(6, 5)
self.gridLayout_4.setRowStretch(7, 1)
self.gridLayout_4.setRowStretch(8, 5)
self.gridLayout_4.setRowStretch(9, 1)
self.gridLayout_4.setRowStretch(10, 5)
self.gridLayout_4.setColumnStretch(0, 1)
self.gridLayout_4.setColumnStretch(1, 2)
self.gridLayout.addWidget(self.groupBox_right, 0, 2, 1, 1)
self.gridLayout.setColumnStretch(0, 4)
self.gridLayout.setColumnStretch(1, 15)
self.gridLayout.setColumnStretch(2, 4)
MainWindow_bcg_quality_label.setCentralWidget(self.centralwidget)
self.statusbar = QStatusBar(MainWindow_bcg_quality_label)
self.statusbar.setObjectName(u"statusbar")
MainWindow_bcg_quality_label.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow_bcg_quality_label)
QMetaObject.connectSlotsByName(MainWindow_bcg_quality_label)
# setupUi
def retranslateUi(self, MainWindow_bcg_quality_label):
MainWindow_bcg_quality_label.setWindowTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"BCG\u7684\u8d28\u91cf\u6807\u6ce8", None))
self.groupBox_canvas.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u7ed8\u56fe\u533a", None))
self.groupBox_left.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"BCG\u7684\u8d28\u91cf\u6807\u6ce8", None))
self.pushButton_input_setting.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u5bfc\u5165\u8bbe\u7f6e", None))
self.pushButton_input.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u5f00\u59cb\u5bfc\u5165", None))
self.groupBox_status.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u8fd0\u884c\u72b6\u6001", None))
self.label_5.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u5f53\u524d\u7247\u6bb5\u65f6\u95f4", None))
self.label_6.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u5f53\u524d\u7247\u6bb5/\u7247\u6bb5\u603b\u6570", None))
self.label_12.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u6700\u957f\u8fde\u7eed\u65f6\u95f4", None))
self.label_13.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u4f53\u52a8\u65f6\u95f4\u5360\u6bd4", None))
self.groupBox_artifact_type.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u4f53\u52a8\u7c7b\u578b", None))
self.checkBox_allin.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u5168\u9009", None))
self.checkBox_type1.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u7c7b\u578b1-\u5267\u70c8\u4f53\u52a8", None))
self.checkBox_type2.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u7c7b\u578b2-\u8109\u51b2\u4f53\u52a8", None))
self.checkBox_type3.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u7c7b\u578b3-\u5e38\u89c4\u4f53\u52a8", None))
self.checkBox_type4.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u7c7b\u578b4-\u7591\u4f3c\u9f3e\u58f0", None))
self.checkBox_type5.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u7c7b\u578b5-\u79bb\u5e8a", None))
self.groupBox_function.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u529f\u80fd", None))
self.pushButton_invalid_signal_label.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u65e0\u6548\u4fe1\u53f7\u6807\u6ce8", None))
self.pushButton_Ctype_signal_label.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"C\u7c7b\u4fe1\u53f7\u6807\u6ce8", None))
self.groupBox_operation.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u64cd\u4f5c", None))
self.pushButton_prev.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"<(A)", None))
self.checkBox_examine_tobeLabeled.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u4ec5\u67e5\u672a\u6807\u7247\u6bb5", None))
self.checkBox_highlight_longest_continuous.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u9ad8\u4eae\u6700\u957f\u8fde\u7eed", None))
self.pushButton_next.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u">(D)", None))
self.label.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u8f93\u5165\u5907\u6ce8", None))
self.checkBox_display_afterfilter.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u53bb\u9664\u5de5\u9891\u566a\u58f0", None))
self.groupBox_4.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u65e5\u5fd7", None))
self.groupBox_right.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u6807\u7b7e\u8bb0\u5f55", None))
self.pushButton_b1.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"b1", None))
self.pushButton_b2.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"b2", None))
self.pushButton_f.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"\u5220\u9664", None))
self.pushButton_a2.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"a2", None))
self.pushButton_a1.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"a1", None))
self.pushButton_c.setText(QCoreApplication.translate("MainWindow_bcg_quality_label", u"c", None))
# retranslateUi

View File

@ -0,0 +1,831 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow_bcg_quality_label</class>
<widget class="QMainWindow" name="MainWindow_bcg_quality_label">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1920</width>
<height>1080</height>
</rect>
</property>
<property name="windowTitle">
<string>BCG的质量标注</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout" columnstretch="4,15,4">
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_canvas">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="title">
<string>绘图区</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_canvas"/>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_left">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="title">
<string>BCG的质量标注</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="2,1,4,1,6,1,6,1,5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_input_setting">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>导入设置</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_input">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>开始导入</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_status">
<property name="title">
<string>运行状态</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>当前片段时间</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>当前片段/片段总数</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>最长连续时间</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>体动时间占比</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_artifact_time_percentage">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_longest_continuous_time">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_data_part_num">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_current_part_time">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="2,1">
<item>
<widget class="QGroupBox" name="groupBox_artifact_type">
<property name="title">
<string>体动类型</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="checkBox_allin">
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>全选</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_type1">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>类型1-剧烈体动</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_type2">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>类型2-脉冲体动</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_type3">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>类型3-常规体动</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_type4">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>类型4-疑似鼾声</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_type5">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>类型5-离床</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_function">
<property name="title">
<string>功能</string>
</property>
<layout class="QGridLayout" name="gridLayout_13">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton_invalid_signal_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>无效信号标注</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton_Ctype_signal_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>C类信号标注</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_operation">
<property name="title">
<string>操作</string>
</property>
<layout class="QGridLayout" name="gridLayout_7" rowstretch="1,1,1,1,3" columnstretch="1,1">
<item row="4" column="0">
<widget class="QPushButton" name="pushButton_prev">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>&lt;(A)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_examine_tobeLabeled">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>仅查未标片段</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_highlight_longest_continuous">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>高亮最长连续</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="pushButton_next">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>&gt;(D)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>输入备注</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_display_afterfilter">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>去除工频噪声</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_remark">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>日志</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QTextBrowser" name="textBrowser_info"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="2">
<widget class="QGroupBox" name="groupBox_right">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="title">
<string>标签记录</string>
</property>
<layout class="QGridLayout" name="gridLayout_4" rowstretch="5,1,5,1,5,1,5,1,5,1,5" columnstretch="1,2">
<item row="7" column="0" colspan="2">
<spacer name="verticalSpacer_9">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="pushButton_b1">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
</font>
</property>
<property name="text">
<string>b1</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QTableWidget" name="tableWidget_c">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="columnCount">
<number>1</number>
</property>
<column/>
</widget>
</item>
<item row="0" column="1">
<widget class="QTableWidget" name="tableWidget_a1">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="columnCount">
<number>1</number>
</property>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>33</number>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>75</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>32</number>
</attribute>
<column/>
</widget>
</item>
<item row="6" column="0">
<widget class="QPushButton" name="pushButton_b2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
</font>
</property>
<property name="text">
<string>b2</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QPushButton" name="pushButton_f">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
</font>
</property>
<property name="text">
<string>删除</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QTableWidget" name="tableWidget_f">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="columnCount">
<number>1</number>
</property>
<column/>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pushButton_a2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
</font>
</property>
<property name="text">
<string>a2</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QTableWidget" name="tableWidget_b1">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="columnCount">
<number>1</number>
</property>
<column/>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="pushButton_a1">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
</font>
</property>
<property name="text">
<string>a1</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QTableWidget" name="tableWidget_b2">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="columnCount">
<number>1</number>
</property>
<column/>
</widget>
</item>
<item row="2" column="1">
<widget class="QTableWidget" name="tableWidget_a2">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="columnCount">
<number>1</number>
</property>
<column/>
</widget>
</item>
<item row="5" column="0" colspan="2">
<spacer name="verticalSpacer_8">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="8" column="0">
<widget class="QPushButton" name="pushButton_c">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
</font>
</property>
<property name="text">
<string>c</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<spacer name="verticalSpacer_10">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -357,14 +357,6 @@ class Ui_MainWindow_label_check(object):
self.horizontalLayout_3.addWidget(self.checkBox_show_reference_line) self.horizontalLayout_3.addWidget(self.checkBox_show_reference_line)
self.pushButton_save = QPushButton(self.groupBox_left)
self.pushButton_save.setObjectName(u"pushButton_save")
sizePolicy.setHeightForWidth(self.pushButton_save.sizePolicy().hasHeightForWidth())
self.pushButton_save.setSizePolicy(sizePolicy)
self.pushButton_save.setFont(font1)
self.horizontalLayout_3.addWidget(self.pushButton_save)
self.verticalLayout_2.addLayout(self.horizontalLayout_3) self.verticalLayout_2.addLayout(self.horizontalLayout_3)
@ -521,7 +513,6 @@ class Ui_MainWindow_label_check(object):
self.label_6.setText(QCoreApplication.translate("MainWindow_label_check", u"\u6700\u5927\u8303\u56f4", None)) self.label_6.setText(QCoreApplication.translate("MainWindow_label_check", u"\u6700\u5927\u8303\u56f4", None))
self.label_8.setText(QCoreApplication.translate("MainWindow_label_check", u"\u79fb\u52a8\u95f4\u9694(ms)", None)) self.label_8.setText(QCoreApplication.translate("MainWindow_label_check", u"\u79fb\u52a8\u95f4\u9694(ms)", None))
self.checkBox_show_reference_line.setText(QCoreApplication.translate("MainWindow_label_check", u"\u7ed8\u5236\u53c2\u8003\u7ebf", None)) self.checkBox_show_reference_line.setText(QCoreApplication.translate("MainWindow_label_check", u"\u7ed8\u5236\u53c2\u8003\u7ebf", None))
self.pushButton_save.setText(QCoreApplication.translate("MainWindow_label_check", u"\u5bfc\u51fa\u6807\u7b7e", None))
self.groupBox_4.setTitle(QCoreApplication.translate("MainWindow_label_check", u"\u65e5\u5fd7", None)) self.groupBox_4.setTitle(QCoreApplication.translate("MainWindow_label_check", u"\u65e5\u5fd7", None))
self.groupBox_right.setTitle(QCoreApplication.translate("MainWindow_label_check", u"\u5cf0\u503c\u5750\u6807\u548c\u4fe1\u606f", None)) self.groupBox_right.setTitle(QCoreApplication.translate("MainWindow_label_check", u"\u5cf0\u503c\u5750\u6807\u548c\u4fe1\u606f", None))
self.label_9.setText(QCoreApplication.translate("MainWindow_label_check", u"\u6570\u636e\u957f\u5ea6(\u70b9\u6570)", None)) self.label_9.setText(QCoreApplication.translate("MainWindow_label_check", u"\u6570\u636e\u957f\u5ea6(\u70b9\u6570)", None))

View File

@ -619,24 +619,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="pushButton_save">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>导出标签</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View File

@ -15,11 +15,11 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon, QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter, QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform) QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QDoubleSpinBox, QGridLayout, QGroupBox, from PySide6.QtWidgets import (QApplication, QCheckBox, QDoubleSpinBox, QGridLayout,
QHBoxLayout, QHeaderView, QLabel, QLineEdit, QGroupBox, QHBoxLayout, QHeaderView, QLabel,
QMainWindow, QPushButton, QRadioButton, QSizePolicy, QLineEdit, QMainWindow, QPushButton, QRadioButton,
QSpacerItem, QStatusBar, QTableWidget, QTableWidgetItem, QSizePolicy, QSpacerItem, QStatusBar, QTableWidget,
QTextBrowser, QVBoxLayout, QWidget) QTableWidgetItem, QTextBrowser, QVBoxLayout, QWidget)
class Ui_MainWindow_resp_quality_label(object): class Ui_MainWindow_resp_quality_label(object):
def setupUi(self, MainWindow_resp_quality_label): def setupUi(self, MainWindow_resp_quality_label):
@ -94,13 +94,13 @@ class Ui_MainWindow_resp_quality_label(object):
self.gridLayout_5.addWidget(self.pushButton_calculate_peaks_save, 2, 0, 1, 1) self.gridLayout_5.addWidget(self.pushButton_calculate_peaks_save, 2, 0, 1, 1)
self.pushButton_input_data_and_label = QPushButton(self.groupBox_left) self.pushButton_input_and_label = QPushButton(self.groupBox_left)
self.pushButton_input_data_and_label.setObjectName(u"pushButton_input_data_and_label") self.pushButton_input_and_label.setObjectName(u"pushButton_input_and_label")
sizePolicy.setHeightForWidth(self.pushButton_input_data_and_label.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.pushButton_input_and_label.sizePolicy().hasHeightForWidth())
self.pushButton_input_data_and_label.setSizePolicy(sizePolicy) self.pushButton_input_and_label.setSizePolicy(sizePolicy)
self.pushButton_input_data_and_label.setFont(font1) self.pushButton_input_and_label.setFont(font1)
self.gridLayout_5.addWidget(self.pushButton_input_data_and_label, 0, 1, 3, 1) self.gridLayout_5.addWidget(self.pushButton_input_and_label, 0, 1, 3, 1)
self.verticalLayout_2.addLayout(self.gridLayout_5) self.verticalLayout_2.addLayout(self.gridLayout_5)
@ -135,14 +135,16 @@ class Ui_MainWindow_resp_quality_label(object):
self.doubleSpinBox_quality_threshold1 = QDoubleSpinBox(self.groupBox_autoqualitylabel_options) self.doubleSpinBox_quality_threshold1 = QDoubleSpinBox(self.groupBox_autoqualitylabel_options)
self.doubleSpinBox_quality_threshold1.setObjectName(u"doubleSpinBox_quality_threshold1") self.doubleSpinBox_quality_threshold1.setObjectName(u"doubleSpinBox_quality_threshold1")
self.doubleSpinBox_quality_threshold1.setFont(font1) self.doubleSpinBox_quality_threshold1.setFont(font1)
self.doubleSpinBox_quality_threshold1.setMaximum(10000.000000000000000) self.doubleSpinBox_quality_threshold1.setMaximum(1.000000000000000)
self.doubleSpinBox_quality_threshold1.setSingleStep(0.100000000000000)
self.gridLayout_3.addWidget(self.doubleSpinBox_quality_threshold1, 0, 1, 1, 1) self.gridLayout_3.addWidget(self.doubleSpinBox_quality_threshold1, 0, 1, 1, 1)
self.doubleSpinBox_quality_threshold2 = QDoubleSpinBox(self.groupBox_autoqualitylabel_options) self.doubleSpinBox_quality_threshold2 = QDoubleSpinBox(self.groupBox_autoqualitylabel_options)
self.doubleSpinBox_quality_threshold2.setObjectName(u"doubleSpinBox_quality_threshold2") self.doubleSpinBox_quality_threshold2.setObjectName(u"doubleSpinBox_quality_threshold2")
self.doubleSpinBox_quality_threshold2.setFont(font1) self.doubleSpinBox_quality_threshold2.setFont(font1)
self.doubleSpinBox_quality_threshold2.setMaximum(10000.000000000000000) self.doubleSpinBox_quality_threshold2.setMaximum(1.000000000000000)
self.doubleSpinBox_quality_threshold2.setSingleStep(0.100000000000000)
self.gridLayout_3.addWidget(self.doubleSpinBox_quality_threshold2, 1, 1, 1, 1) self.gridLayout_3.addWidget(self.doubleSpinBox_quality_threshold2, 1, 1, 1, 1)
@ -157,6 +159,59 @@ class Ui_MainWindow_resp_quality_label(object):
self.verticalLayout_2.addWidget(self.groupBox_autoqualitylabel_options) self.verticalLayout_2.addWidget(self.groupBox_autoqualitylabel_options)
self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.groupBox_artifact_type = QGroupBox(self.groupBox_left)
self.groupBox_artifact_type.setObjectName(u"groupBox_artifact_type")
self.verticalLayout_3 = QVBoxLayout(self.groupBox_artifact_type)
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
self.checkBox_allin = QCheckBox(self.groupBox_artifact_type)
self.checkBox_allin.setObjectName(u"checkBox_allin")
font2 = QFont()
font2.setPointSize(20)
self.checkBox_allin.setFont(font2)
self.checkBox_allin.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_allin)
self.checkBox_type1 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type1.setObjectName(u"checkBox_type1")
self.checkBox_type1.setFont(font1)
self.checkBox_type1.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type1)
self.checkBox_type2 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type2.setObjectName(u"checkBox_type2")
self.checkBox_type2.setFont(font1)
self.checkBox_type2.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type2)
self.checkBox_type3 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type3.setObjectName(u"checkBox_type3")
self.checkBox_type3.setFont(font1)
self.checkBox_type3.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type3)
self.checkBox_type4 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type4.setObjectName(u"checkBox_type4")
self.checkBox_type4.setFont(font1)
self.checkBox_type4.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type4)
self.checkBox_type5 = QCheckBox(self.groupBox_artifact_type)
self.checkBox_type5.setObjectName(u"checkBox_type5")
self.checkBox_type5.setFont(font1)
self.checkBox_type5.setChecked(True)
self.verticalLayout_3.addWidget(self.checkBox_type5)
self.horizontalLayout_2.addWidget(self.groupBox_artifact_type)
self.groupBox_findpeaks_options = QGroupBox(self.groupBox_left) self.groupBox_findpeaks_options = QGroupBox(self.groupBox_left)
self.groupBox_findpeaks_options.setObjectName(u"groupBox_findpeaks_options") self.groupBox_findpeaks_options.setObjectName(u"groupBox_findpeaks_options")
self.gridLayout_2 = QGridLayout(self.groupBox_findpeaks_options) self.gridLayout_2 = QGridLayout(self.groupBox_findpeaks_options)
@ -192,7 +247,11 @@ class Ui_MainWindow_resp_quality_label(object):
self.gridLayout_2.addWidget(self.doubleSpinBox_findpeaks_min_height, 1, 1, 1, 1) self.gridLayout_2.addWidget(self.doubleSpinBox_findpeaks_min_height, 1, 1, 1, 1)
self.verticalLayout_2.addWidget(self.groupBox_findpeaks_options) self.horizontalLayout_2.addWidget(self.groupBox_findpeaks_options)
self.horizontalLayout_2.setStretch(0, 2)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
self.groupBox_threshold_setting = QGroupBox(self.groupBox_left) self.groupBox_threshold_setting = QGroupBox(self.groupBox_left)
self.groupBox_threshold_setting.setObjectName(u"groupBox_threshold_setting") self.groupBox_threshold_setting.setObjectName(u"groupBox_threshold_setting")
@ -201,14 +260,16 @@ class Ui_MainWindow_resp_quality_label(object):
self.doubleSpinBox_fillterMode_custom_low = QDoubleSpinBox(self.groupBox_threshold_setting) self.doubleSpinBox_fillterMode_custom_low = QDoubleSpinBox(self.groupBox_threshold_setting)
self.doubleSpinBox_fillterMode_custom_low.setObjectName(u"doubleSpinBox_fillterMode_custom_low") self.doubleSpinBox_fillterMode_custom_low.setObjectName(u"doubleSpinBox_fillterMode_custom_low")
self.doubleSpinBox_fillterMode_custom_low.setFont(font1) self.doubleSpinBox_fillterMode_custom_low.setFont(font1)
self.doubleSpinBox_fillterMode_custom_low.setMaximum(10000.000000000000000) self.doubleSpinBox_fillterMode_custom_low.setMaximum(1.000000000000000)
self.doubleSpinBox_fillterMode_custom_low.setSingleStep(0.100000000000000)
self.gridLayout_6.addWidget(self.doubleSpinBox_fillterMode_custom_low, 3, 1, 1, 1) self.gridLayout_6.addWidget(self.doubleSpinBox_fillterMode_custom_low, 3, 1, 1, 1)
self.doubleSpinBox_fillterMode_custom_high = QDoubleSpinBox(self.groupBox_threshold_setting) self.doubleSpinBox_fillterMode_custom_high = QDoubleSpinBox(self.groupBox_threshold_setting)
self.doubleSpinBox_fillterMode_custom_high.setObjectName(u"doubleSpinBox_fillterMode_custom_high") self.doubleSpinBox_fillterMode_custom_high.setObjectName(u"doubleSpinBox_fillterMode_custom_high")
self.doubleSpinBox_fillterMode_custom_high.setFont(font1) self.doubleSpinBox_fillterMode_custom_high.setFont(font1)
self.doubleSpinBox_fillterMode_custom_high.setMaximum(10000.000000000000000) self.doubleSpinBox_fillterMode_custom_high.setMaximum(1.000000000000000)
self.doubleSpinBox_fillterMode_custom_high.setSingleStep(0.100000000000000)
self.gridLayout_6.addWidget(self.doubleSpinBox_fillterMode_custom_high, 3, 3, 1, 1) self.gridLayout_6.addWidget(self.doubleSpinBox_fillterMode_custom_high, 3, 3, 1, 1)
@ -229,6 +290,7 @@ class Ui_MainWindow_resp_quality_label(object):
self.radioButton_orgBcg_fillterMode_preset = QRadioButton(self.groupBox_threshold_setting) self.radioButton_orgBcg_fillterMode_preset = QRadioButton(self.groupBox_threshold_setting)
self.radioButton_orgBcg_fillterMode_preset.setObjectName(u"radioButton_orgBcg_fillterMode_preset") self.radioButton_orgBcg_fillterMode_preset.setObjectName(u"radioButton_orgBcg_fillterMode_preset")
self.radioButton_orgBcg_fillterMode_preset.setFont(font1) self.radioButton_orgBcg_fillterMode_preset.setFont(font1)
self.radioButton_orgBcg_fillterMode_preset.setChecked(True)
self.gridLayout_6.addWidget(self.radioButton_orgBcg_fillterMode_preset, 0, 0, 1, 1) self.gridLayout_6.addWidget(self.radioButton_orgBcg_fillterMode_preset, 0, 0, 1, 1)
@ -241,6 +303,7 @@ class Ui_MainWindow_resp_quality_label(object):
self.label_7 = QLabel(self.groupBox_threshold_setting) self.label_7 = QLabel(self.groupBox_threshold_setting)
self.label_7.setObjectName(u"label_7") self.label_7.setObjectName(u"label_7")
self.label_7.setFont(font1) self.label_7.setFont(font1)
self.label_7.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.gridLayout_6.addWidget(self.label_7, 3, 2, 1, 1) self.gridLayout_6.addWidget(self.label_7, 3, 2, 1, 1)
@ -252,6 +315,10 @@ class Ui_MainWindow_resp_quality_label(object):
self.gridLayout_6.addWidget(self.pushButton_refilter_orgBcg, 0, 2, 1, 2) self.gridLayout_6.addWidget(self.pushButton_refilter_orgBcg, 0, 2, 1, 2)
self.gridLayout_6.setColumnStretch(0, 2)
self.gridLayout_6.setColumnStretch(1, 2)
self.gridLayout_6.setColumnStretch(2, 1)
self.gridLayout_6.setColumnStretch(3, 2)
self.verticalLayout_2.addWidget(self.groupBox_threshold_setting) self.verticalLayout_2.addWidget(self.groupBox_threshold_setting)
@ -343,19 +410,6 @@ class Ui_MainWindow_resp_quality_label(object):
self.verticalLayout_2.addWidget(self.groupBox_label_operation) self.verticalLayout_2.addWidget(self.groupBox_label_operation)
self.horizontalLayout_3 = QHBoxLayout()
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.pushButton_save = QPushButton(self.groupBox_left)
self.pushButton_save.setObjectName(u"pushButton_save")
sizePolicy.setHeightForWidth(self.pushButton_save.sizePolicy().hasHeightForWidth())
self.pushButton_save.setSizePolicy(sizePolicy)
self.pushButton_save.setFont(font1)
self.horizontalLayout_3.addWidget(self.pushButton_save)
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
self.groupBox_4 = QGroupBox(self.groupBox_left) self.groupBox_4 = QGroupBox(self.groupBox_left)
self.groupBox_4.setObjectName(u"groupBox_4") self.groupBox_4.setObjectName(u"groupBox_4")
self.verticalLayout_6 = QVBoxLayout(self.groupBox_4) self.verticalLayout_6 = QVBoxLayout(self.groupBox_4)
@ -372,12 +426,9 @@ class Ui_MainWindow_resp_quality_label(object):
self.verticalLayout_2.setStretch(1, 3) self.verticalLayout_2.setStretch(1, 3)
self.verticalLayout_2.setStretch(2, 1) self.verticalLayout_2.setStretch(2, 1)
self.verticalLayout_2.setStretch(3, 3) self.verticalLayout_2.setStretch(3, 3)
self.verticalLayout_2.setStretch(4, 3)
self.verticalLayout_2.setStretch(5, 3)
self.verticalLayout_2.setStretch(6, 1) self.verticalLayout_2.setStretch(6, 1)
self.verticalLayout_2.setStretch(7, 6) self.verticalLayout_2.setStretch(7, 6)
self.verticalLayout_2.setStretch(8, 2) self.verticalLayout_2.setStretch(8, 5)
self.verticalLayout_2.setStretch(9, 5)
self.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1) self.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1)
@ -471,11 +522,18 @@ class Ui_MainWindow_resp_quality_label(object):
self.pushButton_calculate_peaks.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u8ba1\u7b97\u5cf0\u503c\u5e76\u7ed8\u5236", None)) self.pushButton_calculate_peaks.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u8ba1\u7b97\u5cf0\u503c\u5e76\u7ed8\u5236", None))
self.pushButton_input_and_calculate_peaks.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5bfc\u5165\u5e76\u7b97\u6cd5\u5b9a\u4f4d\u5cf0\u503c", None)) self.pushButton_input_and_calculate_peaks.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5bfc\u5165\u5e76\u7b97\u6cd5\u5b9a\u4f4d\u5cf0\u503c", None))
self.pushButton_calculate_peaks_save.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4fdd\u5b58\u5cf0\u503c\u7ed3\u679c", None)) self.pushButton_calculate_peaks_save.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4fdd\u5b58\u5cf0\u503c\u7ed3\u679c", None))
self.pushButton_input_data_and_label.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5bfc\u5165\u5e76\u5f00\u59cb\u6807\u6ce8", None)) self.pushButton_input_and_label.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5bfc\u5165\u5e76\u5f00\u59cb\u6807\u6ce8", None))
self.groupBox_autoqualitylabel_options.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4eba\u5de5\u6807\u6ce8\u9608\u503c\u8bbe\u7f6e", None)) self.groupBox_autoqualitylabel_options.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4eba\u5de5\u6807\u6ce8\u9608\u503c\u8bbe\u7f6e", None))
self.label_6.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"threshold[1]", None)) self.label_6.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"threshold[1]", None))
self.label_5.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"threshold[0]", None)) self.label_5.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"threshold[0]", None))
self.pushButton_autoqualitylabel_recalculate.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5e94\u7528\u5e76\u8ba1\u7b97", None)) self.pushButton_autoqualitylabel_recalculate.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5e94\u7528\u5e76\u8ba1\u7b97", None))
self.groupBox_artifact_type.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4f53\u52a8\u7c7b\u578b", None))
self.checkBox_allin.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5168\u9009", None))
self.checkBox_type1.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u7c7b\u578b1-\u5267\u70c8\u4f53\u52a8", None))
self.checkBox_type2.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u7c7b\u578b2-\u8109\u51b2\u4f53\u52a8", None))
self.checkBox_type3.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u7c7b\u578b3-\u5e38\u89c4\u4f53\u52a8", None))
self.checkBox_type4.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u7c7b\u578b4-\u7591\u4f3c\u9f3e\u58f0", None))
self.checkBox_type5.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u7c7b\u578b5-\u79bb\u5e8a", None))
self.groupBox_findpeaks_options.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5bfb\u5cf0\u53c2\u6570\u8bbe\u7f6e", None)) self.groupBox_findpeaks_options.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5bfb\u5cf0\u53c2\u6570\u8bbe\u7f6e", None))
self.label_4.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u6700\u5c0f\u95f4\u9694", None)) self.label_4.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u6700\u5c0f\u95f4\u9694", None))
self.label_3.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u6700\u5c0f\u9ad8\u5ea6", None)) self.label_3.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u6700\u5c0f\u9ad8\u5ea6", None))
@ -494,7 +552,6 @@ class Ui_MainWindow_resp_quality_label(object):
self.pushButton_valid.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u53ef\u7528\uff08F\uff09", None)) self.pushButton_valid.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u53ef\u7528\uff08F\uff09", None))
self.pushButton_prev.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4e0a\u4e00\u6bb5(A)", None)) self.pushButton_prev.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4e0a\u4e00\u6bb5(A)", None))
self.pushButton_next.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4e0b\u4e00\u6bb5(D)", None)) self.pushButton_next.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u4e0b\u4e00\u6bb5(D)", None))
self.pushButton_save.setText(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u5bfc\u51fa\u6807\u7b7e", None))
self.groupBox_4.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u65e5\u5fd7", None)) self.groupBox_4.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u65e5\u5fd7", None))
self.groupBox_right.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u547c\u5438\u53ef\u7528\u6027\u53ca\u95f4\u671f\u6807\u6ce8", None)) self.groupBox_right.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u547c\u5438\u53ef\u7528\u6027\u53ca\u95f4\u671f\u6807\u6ce8", None))
self.groupBox.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u9891\u8c31", None)) self.groupBox.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label", u"\u9891\u8c31", None))

View File

@ -42,7 +42,7 @@
<property name="title"> <property name="title">
<string>呼吸可用性及间期标注</string> <string>呼吸可用性及间期标注</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="2,3,1,3,3,3,1,6,2,5"> <layout class="QVBoxLayout" name="verticalLayout_2" stretch="2,3,1,3,0,0,1,6,5">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
@ -122,7 +122,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="1" rowspan="3"> <item row="0" column="1" rowspan="3">
<widget class="QPushButton" name="pushButton_input_data_and_label"> <widget class="QPushButton" name="pushButton_input_and_label">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -204,7 +204,10 @@
</font> </font>
</property> </property>
<property name="maximum"> <property name="maximum">
<double>10000.000000000000000</double> <double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
@ -216,7 +219,10 @@
</font> </font>
</property> </property>
<property name="maximum"> <property name="maximum">
<double>10000.000000000000000</double> <double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
@ -242,80 +248,183 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox_findpeaks_options"> <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="2,0">
<property name="title"> <item>
<string>寻峰参数设置</string> <widget class="QGroupBox" name="groupBox_artifact_type">
</property> <property name="title">
<layout class="QGridLayout" name="gridLayout_2"> <string>体动类型</string>
<item row="0" column="0"> </property>
<widget class="QLabel" name="label_4"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="sizePolicy"> <item>
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <widget class="QCheckBox" name="checkBox_allin">
<horstretch>0</horstretch> <property name="font">
<verstretch>0</verstretch> <font>
</sizepolicy> <pointsize>20</pointsize>
</property> </font>
<property name="font"> </property>
<font> <property name="text">
<pointsize>12</pointsize> <string>全选</string>
</font> </property>
</property> <property name="checked">
<property name="text"> <bool>true</bool>
<string>最小间隔</string> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item row="0" column="1"> <widget class="QCheckBox" name="checkBox_type1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_findpeaks_min_interval"> <property name="font">
<property name="font"> <font>
<font> <pointsize>12</pointsize>
<pointsize>12</pointsize> </font>
</font> </property>
</property> <property name="text">
<property name="maximum"> <string>类型1-剧烈体动</string>
<double>10000.000000000000000</double> </property>
</property> <property name="checked">
</widget> <bool>true</bool>
</item> </property>
<item row="1" column="0"> </widget>
<widget class="QLabel" name="label_3"> </item>
<property name="sizePolicy"> <item>
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <widget class="QCheckBox" name="checkBox_type2">
<horstretch>0</horstretch> <property name="font">
<verstretch>0</verstretch> <font>
</sizepolicy> <pointsize>12</pointsize>
</property> </font>
<property name="font"> </property>
<font> <property name="text">
<pointsize>12</pointsize> <string>类型2-脉冲体动</string>
</font> </property>
</property> <property name="checked">
<property name="text"> <bool>true</bool>
<string>最小高度</string> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item row="1" column="1"> <widget class="QCheckBox" name="checkBox_type3">
<widget class="QDoubleSpinBox" name="doubleSpinBox_findpeaks_min_height"> <property name="font">
<property name="font"> <font>
<font> <pointsize>12</pointsize>
<pointsize>12</pointsize> </font>
</font> </property>
</property> <property name="text">
<property name="maximum"> <string>类型3-常规体动</string>
<double>10000.000000000000000</double> </property>
</property> <property name="checked">
</widget> <bool>true</bool>
</item> </property>
</layout> </widget>
</widget> </item>
<item>
<widget class="QCheckBox" name="checkBox_type4">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>类型4-疑似鼾声</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_type5">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>类型5-离床</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_findpeaks_options">
<property name="title">
<string>寻峰参数设置</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>最小间隔</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_findpeaks_min_interval">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>最小高度</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_findpeaks_min_height">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox_threshold_setting"> <widget class="QGroupBox" name="groupBox_threshold_setting">
<property name="title"> <property name="title">
<string>OrgBCG带通滤波频率设置</string> <string>OrgBCG带通滤波频率设置</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_6"> <layout class="QGridLayout" name="gridLayout_6" columnstretch="2,2,1,2">
<item row="3" column="1"> <item row="3" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_fillterMode_custom_low"> <widget class="QDoubleSpinBox" name="doubleSpinBox_fillterMode_custom_low">
<property name="font"> <property name="font">
@ -324,7 +433,10 @@
</font> </font>
</property> </property>
<property name="maximum"> <property name="maximum">
<double>10000.000000000000000</double> <double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
@ -336,7 +448,10 @@
</font> </font>
</property> </property>
<property name="maximum"> <property name="maximum">
<double>10000.000000000000000</double> <double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
@ -380,6 +495,9 @@
<property name="text"> <property name="text">
<string>预设</string> <string>预设</string>
</property> </property>
<property name="checked">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
@ -404,6 +522,9 @@
<property name="text"> <property name="text">
<string>~</string> <string>~</string>
</property> </property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget> </widget>
</item> </item>
<item row="0" column="2" colspan="2"> <item row="0" column="2" colspan="2">
@ -609,28 +730,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="pushButton_save">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>导出标签</string>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBox_4"> <widget class="QGroupBox" name="groupBox_4">
<property name="title"> <property name="title">

View File

@ -0,0 +1,178 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'bcg_quality_label_input_setting.ui'
##
## Created by: Qt User Interface Compiler version 6.8.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QGridLayout, QGroupBox, QHBoxLayout,
QLabel, QMainWindow, QPlainTextEdit, QPushButton,
QRadioButton, QSizePolicy, QSpacerItem, QSpinBox,
QStatusBar, QVBoxLayout, QWidget)
class Ui_MainWindow_bcg_quality_label_input_setting(object):
def setupUi(self, MainWindow_bcg_quality_label_input_setting):
if not MainWindow_bcg_quality_label_input_setting.objectName():
MainWindow_bcg_quality_label_input_setting.setObjectName(u"MainWindow_bcg_quality_label_input_setting")
MainWindow_bcg_quality_label_input_setting.resize(540, 540)
self.centralwidget = QWidget(MainWindow_bcg_quality_label_input_setting)
self.centralwidget.setObjectName(u"centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.pushButton_cancel = QPushButton(self.centralwidget)
self.pushButton_cancel.setObjectName(u"pushButton_cancel")
font = QFont()
font.setPointSize(12)
self.pushButton_cancel.setFont(font)
self.gridLayout.addWidget(self.pushButton_cancel, 1, 3, 1, 1)
self.groupBox = QGroupBox(self.centralwidget)
self.groupBox.setObjectName(u"groupBox")
font1 = QFont()
font1.setPointSize(10)
self.groupBox.setFont(font1)
self.verticalLayout_2 = QVBoxLayout(self.groupBox)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.groupBox_file_path_input_signal_BCG = QGroupBox(self.groupBox)
self.groupBox_file_path_input_signal_BCG.setObjectName(u"groupBox_file_path_input_signal_BCG")
self.verticalLayout_5 = QVBoxLayout(self.groupBox_file_path_input_signal_BCG)
self.verticalLayout_5.setObjectName(u"verticalLayout_5")
self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.label_2 = QLabel(self.groupBox_file_path_input_signal_BCG)
self.label_2.setObjectName(u"label_2")
self.label_2.setFont(font)
self.horizontalLayout_2.addWidget(self.label_2)
self.spinBox_input_freq_signal_BCG = QSpinBox(self.groupBox_file_path_input_signal_BCG)
self.spinBox_input_freq_signal_BCG.setObjectName(u"spinBox_input_freq_signal_BCG")
self.spinBox_input_freq_signal_BCG.setFont(font)
self.spinBox_input_freq_signal_BCG.setMinimum(1)
self.spinBox_input_freq_signal_BCG.setMaximum(1000000)
self.horizontalLayout_2.addWidget(self.spinBox_input_freq_signal_BCG)
self.verticalLayout_5.addLayout(self.horizontalLayout_2)
self.plainTextEdit_file_path_input_signal_BCG = QPlainTextEdit(self.groupBox_file_path_input_signal_BCG)
self.plainTextEdit_file_path_input_signal_BCG.setObjectName(u"plainTextEdit_file_path_input_signal_BCG")
self.verticalLayout_5.addWidget(self.plainTextEdit_file_path_input_signal_BCG)
self.verticalLayout_5.setStretch(0, 1)
self.verticalLayout_5.setStretch(1, 2)
self.verticalLayout_2.addWidget(self.groupBox_file_path_input_signal_BCG)
self.groupBox_file_path_input_artifact = QGroupBox(self.groupBox)
self.groupBox_file_path_input_artifact.setObjectName(u"groupBox_file_path_input_artifact")
self.verticalLayout_6 = QVBoxLayout(self.groupBox_file_path_input_artifact)
self.verticalLayout_6.setObjectName(u"verticalLayout_6")
self.plainTextEdit_file_path_input_artifact = QPlainTextEdit(self.groupBox_file_path_input_artifact)
self.plainTextEdit_file_path_input_artifact.setObjectName(u"plainTextEdit_file_path_input_artifact")
self.verticalLayout_6.addWidget(self.plainTextEdit_file_path_input_artifact)
self.verticalLayout_6.setStretch(0, 2)
self.verticalLayout_2.addWidget(self.groupBox_file_path_input_artifact)
self.groupBox_file_path_save = QGroupBox(self.groupBox)
self.groupBox_file_path_save.setObjectName(u"groupBox_file_path_save")
self.verticalLayout_4 = QVBoxLayout(self.groupBox_file_path_save)
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
self.plainTextEdit_file_path_save = QPlainTextEdit(self.groupBox_file_path_save)
self.plainTextEdit_file_path_save.setObjectName(u"plainTextEdit_file_path_save")
self.verticalLayout_4.addWidget(self.plainTextEdit_file_path_save)
self.verticalLayout_2.addWidget(self.groupBox_file_path_save)
self.groupBox_display_mode = QGroupBox(self.groupBox)
self.groupBox_display_mode.setObjectName(u"groupBox_display_mode")
self.horizontalLayout = QHBoxLayout(self.groupBox_display_mode)
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.horizontalLayout.addItem(self.horizontalSpacer)
self.radioButton_30s_mode = QRadioButton(self.groupBox_display_mode)
self.radioButton_30s_mode.setObjectName(u"radioButton_30s_mode")
self.radioButton_30s_mode.setFont(font)
self.radioButton_30s_mode.setChecked(True)
self.horizontalLayout.addWidget(self.radioButton_30s_mode)
self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.horizontalLayout.addItem(self.horizontalSpacer_3)
self.radioButton_10s_mode = QRadioButton(self.groupBox_display_mode)
self.radioButton_10s_mode.setObjectName(u"radioButton_10s_mode")
self.radioButton_10s_mode.setFont(font)
self.horizontalLayout.addWidget(self.radioButton_10s_mode)
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.horizontalLayout.addItem(self.horizontalSpacer_2)
self.verticalLayout_2.addWidget(self.groupBox_display_mode)
self.verticalLayout_2.setStretch(0, 3)
self.verticalLayout_2.setStretch(1, 2)
self.verticalLayout_2.setStretch(2, 2)
self.verticalLayout_2.setStretch(3, 2)
self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 4)
self.pushButton_confirm = QPushButton(self.centralwidget)
self.pushButton_confirm.setObjectName(u"pushButton_confirm")
self.pushButton_confirm.setFont(font)
self.gridLayout.addWidget(self.pushButton_confirm, 1, 2, 1, 1)
MainWindow_bcg_quality_label_input_setting.setCentralWidget(self.centralwidget)
self.statusbar = QStatusBar(MainWindow_bcg_quality_label_input_setting)
self.statusbar.setObjectName(u"statusbar")
MainWindow_bcg_quality_label_input_setting.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow_bcg_quality_label_input_setting)
QMetaObject.connectSlotsByName(MainWindow_bcg_quality_label_input_setting)
# setupUi
def retranslateUi(self, MainWindow_bcg_quality_label_input_setting):
MainWindow_bcg_quality_label_input_setting.setWindowTitle(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u5bfc\u5165\u8bbe\u7f6e", None))
self.pushButton_cancel.setText(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u53d6\u6d88", None))
self.groupBox.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
self.groupBox_file_path_input_signal_BCG.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u540c\u6b65\u540e\u7684BCG\u8def\u5f84", None))
self.label_2.setText(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u91c7\u6837\u7387(Hz)\uff1a", None))
self.plainTextEdit_file_path_input_signal_BCG.setPlainText("")
self.plainTextEdit_file_path_input_signal_BCG.setPlaceholderText(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
self.groupBox_file_path_input_artifact.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u4f53\u52a8Artifact_a\u8def\u5f84", None))
self.plainTextEdit_file_path_input_artifact.setPlainText("")
self.plainTextEdit_file_path_input_artifact.setPlaceholderText(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
self.groupBox_file_path_save.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"BCG\u8d28\u91cf\u6807\u7b7e\u4fdd\u5b58\u8def\u5f84", None))
self.plainTextEdit_file_path_save.setPlaceholderText(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u4fdd\u5b58\u8def\u5f84", None))
self.groupBox_display_mode.setTitle(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u663e\u793a\u6a21\u5f0f", None))
self.radioButton_30s_mode.setText(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"30s\u6a21\u5f0f", None))
self.radioButton_10s_mode.setText(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"10s\u6a21\u5f0f", None))
self.pushButton_confirm.setText(QCoreApplication.translate("MainWindow_bcg_quality_label_input_setting", u"\u786e\u5b9a", None))
# retranslateUi

View File

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow_bcg_quality_label_input_setting</class>
<widget class="QMainWindow" name="MainWindow_bcg_quality_label_input_setting">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>540</width>
<height>540</height>
</rect>
</property>
<property name="windowTitle">
<string>导入设置</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="3">
<widget class="QPushButton" name="pushButton_cancel">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>取消</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QGroupBox" name="groupBox">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="title">
<string>文件路径</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="3,2,2,2">
<item>
<widget class="QGroupBox" name="groupBox_file_path_input_signal_BCG">
<property name="title">
<string>同步后的BCG路径</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="1,2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>采样率(Hz)</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_input_freq_signal_BCG">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_file_path_input_signal_BCG">
<property name="plainText">
<string/>
</property>
<property name="placeholderText">
<string>文件路径</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_file_path_input_artifact">
<property name="title">
<string>体动Artifact_a路径</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6" stretch="2">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_file_path_input_artifact">
<property name="plainText">
<string/>
</property>
<property name="placeholderText">
<string>文件路径</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_file_path_save">
<property name="title">
<string>BCG质量标签保存路径</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_file_path_save">
<property name="placeholderText">
<string>保存路径</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_display_mode">
<property name="title">
<string>显示模式</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="radioButton_30s_mode">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>30s模式</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="radioButton_10s_mode">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>10s模式</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton_confirm">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>确定</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -100,10 +100,10 @@ class Ui_MainWindow_resp_quality_label_input_setting(object):
self.verticalLayout_3.addLayout(self.horizontalLayout_3) self.verticalLayout_3.addLayout(self.horizontalLayout_3)
self.plainTextEdit_file_path_input_Tho = QPlainTextEdit(self.groupBox_file_path_input_Tho) self.plainTextEdit_file_path_input_signal_Tho = QPlainTextEdit(self.groupBox_file_path_input_Tho)
self.plainTextEdit_file_path_input_Tho.setObjectName(u"plainTextEdit_file_path_input_Tho") self.plainTextEdit_file_path_input_signal_Tho.setObjectName(u"plainTextEdit_file_path_input_signal_Tho")
self.verticalLayout_3.addWidget(self.plainTextEdit_file_path_input_Tho) self.verticalLayout_3.addWidget(self.plainTextEdit_file_path_input_signal_Tho)
self.verticalLayout_3.setStretch(0, 1) self.verticalLayout_3.setStretch(0, 1)
self.verticalLayout_3.setStretch(1, 2) self.verticalLayout_3.setStretch(1, 2)
@ -181,8 +181,8 @@ class Ui_MainWindow_resp_quality_label_input_setting(object):
self.plainTextEdit_file_path_input_signal_OrgBCG.setPlaceholderText(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None)) self.plainTextEdit_file_path_input_signal_OrgBCG.setPlaceholderText(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
self.groupBox_file_path_input_Tho.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u540c\u6b65\u540e\u7684Effort Tho\u8def\u5f84", None)) self.groupBox_file_path_input_Tho.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u540c\u6b65\u540e\u7684Effort Tho\u8def\u5f84", None))
self.label_3.setText(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u91c7\u6837\u7387(Hz)\uff1a", None)) self.label_3.setText(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u91c7\u6837\u7387(Hz)\uff1a", None))
self.plainTextEdit_file_path_input_Tho.setPlainText("") self.plainTextEdit_file_path_input_signal_Tho.setPlainText("")
self.plainTextEdit_file_path_input_Tho.setPlaceholderText(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None)) self.plainTextEdit_file_path_input_signal_Tho.setPlaceholderText(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
self.groupBox_file_path_input_artifact.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u4f53\u52a8Artifact_a\u8def\u5f84", None)) self.groupBox_file_path_input_artifact.setTitle(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u4f53\u52a8Artifact_a\u8def\u5f84", None))
self.plainTextEdit_file_path_input_artifact.setPlainText("") self.plainTextEdit_file_path_input_artifact.setPlainText("")
self.plainTextEdit_file_path_input_artifact.setPlaceholderText(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None)) self.plainTextEdit_file_path_input_artifact.setPlaceholderText(QCoreApplication.translate("MainWindow_resp_quality_label_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))

View File

@ -126,7 +126,7 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QPlainTextEdit" name="plainTextEdit_file_path_input_Tho"> <widget class="QPlainTextEdit" name="plainTextEdit_file_path_input_signal_Tho">
<property name="plainText"> <property name="plainText">
<string/> <string/>
</property> </property>

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`