Compare commits

...

2 Commits

Author SHA1 Message Date
mmmistgun
a0865d63a7 add README 2022-03-29 22:34:23 +08:00
mmmistgun
d7725857a9 添加主程序接口
添加血氧信号与标签的显示
调整了信号顺序
添加日志模块
添加程序注释
2022-03-29 22:18:46 +08:00
5 changed files with 802 additions and 307 deletions

145
.gitignore vendored
View File

@ -1,145 +0,0 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# custom
Data/*
.idea/
history/

41
Main_Quality_Relabel.py Normal file
View File

@ -0,0 +1,41 @@
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:Marques
@file:Main_Quality_Relabel.py
@email:admin@marques22.com
@email:2021022362@m.scnu.edu.cn
@time:2022/03/28
"""
from utils.Quality_Relabel import Quality_Relabel
# start-----一般不用修改------
# 绘图时的采样率
frequency = 100
# 心晓数据采样率
bcg_frequency = 1000
# end-----一般不用修改------
# 要遍历的事件
# 可选一个或多个 "Hypopnea" "Central apnea" "Obstructive apnea" "Mixed apnea"
focus_event_list = ["Obstructive apnea"]
# 信号显示事件前多少秒
front_add_second = 60
# 信号显示事件后多少秒
back_add_second = 60
# 样本编号
sampNo = 670
# 从第几个心晓事件数量开始
start_bcg_index = 0
# 用于心晓信号前面有一部分信号不可用PSG事件第几个事件对应于心晓第一个事件
shifting = 0
if __name__ == '__main__':
qualityRelabel = Quality_Relabel(sampNo=sampNo, frequency=frequency, bcg_frequency=bcg_frequency,
focus_event_list=focus_event_list)
qualityRelabel.show_all_event(start_bcg_index=start_bcg_index,
shifting=shifting,
front_add_second=front_add_second,
back_add_second=back_add_second)

View File

@ -19,12 +19,20 @@ Quality_Relabel 主目录
```
## 测试数据集
670 [测试数据集](https://kod.server.marques22.com/#s/799gDeDw)
## 程序流程框图
![流程框图](graph/Quality_Relabel.svg)
## TODO
2022-03-27 22:27
1. 完成启动入口(预计半天)
2. 完成参数说明(预计半天)
1. ~~完成启动入口(预计半天)~~
2. ~~完成参数说明(预计半天)~~
3. 导出PSG所有标签(额外的工作)
4. 迁移BCG标签中文字符切换目前已经完成目前存在ubuntu需要文件重命名(预计一小时)
5. 完成日志记录模块(预计半天)
5. ~~完成日志记录模块(预计半天)~~

608
graph/Quality_Relabel.svg Normal file
View File

@ -0,0 +1,608 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- 由 Microsoft Visio, SVG Export 生成 Quality_Relabel.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="11.6929in" height="8.26772in"
viewBox="0 0 841.89 595.276" xml:space="preserve" color-interpolation-filters="sRGB" class="st10">
<v:documentProperties v:langID="2052" v:metric="true" v:viewMarkup="false">
<v:userDefs>
<v:ud v:nameU="msvNoAutoConnect" v:val="VT0(0):26"/>
</v:userDefs>
</v:documentProperties>
<style type="text/css">
<![CDATA[
.st1 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
.st2 {fill:#000000;font-family:黑体;font-size:0.833336em}
.st3 {font-size:1em}
.st4 {font-family:Calibri;font-size:1em}
.st5 {fill:#000000;font-family:Calibri;font-size:0.833336em}
.st6 {font-family:黑体;font-size:1em}
.st7 {marker-end:url(#mrkr4-33);stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.2376}
.st8 {fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:0.086161879895561}
.st9 {fill:#000000;font-family:黑体;font-size:0.666664em}
.st10 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
]]>
</style>
<defs id="Markers">
<g id="lend4">
<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"/>
</g>
<marker id="mrkr4-33" class="st8" v:arrowType="4" v:arrowSize="2" v:setback="23.2121" refX="-23.212121212121" orient="auto"
markerUnits="strokeWidth" overflow="visible">
<use xlink:href="#lend4" transform="scale(-11.606060606061,-11.606060606061) "/>
</marker>
</defs>
<g v:mID="0" v:index="1" v:groupContext="foregroundPage">
<v:userDefs>
<v:ud v:nameU="msvThemeOrder" v:val="VT0(0):26"/>
</v:userDefs>
<title>页-1</title>
<v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394"
v:shadowOffsetY="-8.50394"/>
<v:layer v:name="流程图" v:index="0"/>
<v:layer v:name="连接线" v:index="1"/>
<g id="shape1-1" v:mID="1" v:groupContext="shape" v:layerMember="0" transform="translate(49.6063,-360)">
<title>开始/结束</title>
<desc>开始</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.39370078740157):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.39370078740157):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="581.102" width="70.87" height="28.3465"/>
<path d="M14.17 595.28 L56.69 595.28 A14.1732 14.1732 -180 0 0 56.69 566.93 L14.17 566.93 A14.1732 14.1732 -180 1 0 14.17
595.28 Z" class="st1"/>
<text x="25.43" y="584.43" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>开始</text> </g>
<g id="shape2-4" v:mID="2" v:groupContext="shape" v:layerMember="0" transform="translate(160.157,-416.693)">
<title>数据</title>
<desc>输入心晓信号 心晓事件标签</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="50.315" cy="574.016" width="67.09" height="42.5197"/>
<path d="M-10.63 595.28 L90 595.28 L111.26 552.76 L10.63 552.76 L-10.63 595.28 Z" class="st1"/>
<text x="20.31" y="570.69" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>输入心晓信号<v:newlineChar/><tspan
x="20.31" dy="1.331em" class="st3">心晓事件标签</tspan></text> </g>
<g id="shape5-8" v:mID="5" v:groupContext="shape" v:layerMember="0" transform="translate(160.157,-274.961)">
<title>数据.5</title>
<desc>输入PSG信号 PSG事件标签</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="50.315" cy="574.016" width="67.09" height="42.5197"/>
<path d="M-10.63 595.28 L90 595.28 L111.26 552.76 L10.63 552.76 L-10.63 595.28 Z" class="st1"/>
<text x="22.28" y="570.69" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>输入<tspan class="st4">PSG</tspan>信号<v:newlineChar/><tspan
x="22.28" dy="1.331em" class="st4">PSG</tspan>事件标签</text> </g>
<g id="shape7-13" v:mID="7" v:groupContext="shape" v:layerMember="1" transform="translate(113.386,-367.087)">
<title>动态连接线.7</title>
</g>
<g id="shape8-14" v:mID="8" v:groupContext="shape" v:layerMember="0" transform="translate(283.465,-479.055)">
<title>流程</title>
<desc>20Hz三阶巴特沃斯低通滤波器</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="41.1024" cy="574.016" width="82.21" height="42.5197"/>
<rect x="0" y="552.756" width="82.2047" height="42.5197" class="st1"/>
<text x="5.94" y="570.69" class="st5" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>20Hz<tspan class="st6">三阶巴特沃</tspan><tspan
x="11.1" dy="1.331em" class="st6">斯低通滤波器</tspan></text> </g>
<g id="shape9-19" v:mID="9" v:groupContext="shape" v:layerMember="0" transform="translate(283.465,-416.693)">
<title>流程.9</title>
<desc>0.7Hz三阶巴特沃斯低通滤波器</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="41.1024" cy="574.016" width="82.21" height="42.5197"/>
<rect x="0" y="552.756" width="82.2047" height="42.5197" class="st1"/>
<text x="4.68" y="570.69" class="st5" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>0.7Hz<tspan
class="st6">三阶巴特沃</tspan><tspan x="11.1" dy="1.331em" class="st6">斯低通滤波器</tspan></text> </g>
<g id="shape11-24" v:mID="11" v:groupContext="shape" v:layerMember="0" transform="translate(283.465,-274.961)">
<title>流程.11</title>
<desc>根据采样率 重采样</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="41.1024" cy="574.016" width="82.21" height="42.5197"/>
<rect x="0" y="552.756" width="82.2047" height="42.5197" class="st1"/>
<text x="16.1" y="570.69" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>根据采样率<v:newlineChar/><tspan
x="26.1" dy="1.331em" class="st3">重采样</tspan></text> </g>
<g id="shape17-28" v:mID="17" v:groupContext="shape" v:layerMember="1" transform="translate(260.787,-437.953)">
<title>动态连接线.17</title>
<path d="M0 595.28 L10.63 595.28 L10.63 532.91 L17.16 532.91" class="st7"/>
</g>
<g id="shape18-34" v:mID="18" v:groupContext="shape" v:layerMember="1" transform="translate(260.787,-430.866)">
<title>动态连接线.18</title>
<path d="M0 588.19 L17.16 588.19" class="st7"/>
</g>
<g id="shape19-39" v:mID="19" v:groupContext="shape" v:layerMember="1" transform="translate(260.787,-289.134)">
<title>动态连接线.19</title>
<path d="M0 588.19 L17.16 588.19" class="st7"/>
</g>
<g id="shape20-44" v:mID="20" v:groupContext="shape" v:layerMember="1" transform="translate(120.472,-374.173)">
<title>动态连接线</title>
<path d="M0 595.28 L21.26 595.28 L21.26 531.5 L34.17 531.5" class="st7"/>
</g>
<g id="shape21-49" v:mID="21" v:groupContext="shape" v:layerMember="1" transform="translate(120.472,-374.173)">
<title>动态连接线.21</title>
<path d="M0 595.28 L21.26 595.28 L21.26 673.23 L34.17 673.23" class="st7"/>
</g>
<g id="shape24-54" v:mID="24" v:groupContext="shape" v:layerMember="0" transform="translate(447.874,-443.622)">
<title>数据.24</title>
<desc>提取获得 心晓 心晓呼吸 ABD THO Flow T Flow P SpO2</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(1.4566929133858):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="537.874" width="47.25" height="114.803"/>
<path d="M-17.72 595.28 L53.15 595.28 L88.58 480.47 L17.72 480.47 L-17.72 595.28 Z" class="st1"/>
<text x="15.43" y="497.89" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>提取获得<v:newlineChar/><tspan
x="25.43" dy="1.331em" class="st3">心晓<v:newlineChar/></tspan><tspan x="15.43" dy="1.331em" class="st3">心晓呼吸<v:newlineChar/></tspan><tspan
x="26.74" dy="1.233em" class="st4">ABD<v:newlineChar/></tspan><tspan x="26.57" dy="1.2em" class="st4">THO<v:newlineChar/></tspan><tspan
x="22.21" dy="1.2em" class="st4">Flow T<v:newlineChar/></tspan><tspan x="22.06" dy="1.2em" class="st4">Flow P<v:newlineChar/></tspan><tspan
x="24.66" dy="1.2em" class="st4">SpO2</tspan></text> </g>
<g id="shape25-64" v:mID="25" v:groupContext="shape" v:layerMember="1" transform="translate(365.669,-493.583)">
<title>动态连接线.25</title>
<path d="M0 588.54 L21.26 588.54 L21.26 587.83 L76.69 587.83" class="st7"/>
</g>
<g id="shape26-69" v:mID="26" v:groupContext="shape" v:layerMember="1" transform="translate(365.669,-437.953)">
<title>动态连接线.26</title>
<path d="M0 595.28 L21.26 595.28 L21.26 532.2 L76.69 532.2" class="st7"/>
</g>
<g id="shape27-74" v:mID="27" v:groupContext="shape" v:layerMember="1" transform="translate(365.669,-296.22)">
<title>动态连接线.27</title>
<path d="M0 595.28 L21.26 595.28 L21.26 390.47 L76.69 390.47" class="st7"/>
</g>
<g id="shape29-79" v:mID="29" v:groupContext="shape" v:layerMember="0" transform="translate(586.772,-464.173)">
<title>判定</title>
<desc>根据心晓事件个数遍历</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="41.1024" cy="558.425" width="68.51" height="55.2756"/>
<path d="M0 558.43 L41.1 521.57 L82.2 558.43 L41.1 595.28 L0 558.43 Z" class="st1"/>
<text x="11.1" y="554.77" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>根据心晓事件<tspan x="21.1"
dy="1.298em" class="st3">个数遍历</tspan></text> </g>
<g id="shape30-83" v:mID="30" v:groupContext="shape" v:layerMember="0" transform="translate(724.252,-486.85)">
<title>开始/结束.30</title>
<desc>结束</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.39370078740157):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.39370078740157):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="581.102" width="70.87" height="28.3465"/>
<path d="M14.17 595.28 L56.69 595.28 A14.1732 14.1732 -180 0 0 56.69 566.93 L14.17 566.93 A14.1732 14.1732 -180 1 0 14.17
595.28 Z" class="st1"/>
<text x="27.43" y="583.77" class="st9" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>结束</text> </g>
<g id="shape31-86" v:mID="31" v:groupContext="shape" v:layerMember="0" transform="translate(532.913,-379.134)">
<title>流程.31</title>
<desc>获取PSG事件 长度、标签</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="70.87" height="42.5197"/>
<rect x="0" y="552.756" width="70.8661" height="42.5197" class="st1"/>
<text x="13.01" y="571.35" class="st9" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>获取<tspan class="st4">PSG</tspan>事件<v:newlineChar/><tspan
x="15.43" dy="1.331em" class="st3">长度</tspan>、标签</text> </g>
<g id="shape32-91" v:mID="32" v:groupContext="shape" v:layerMember="0" transform="translate(637.795,-379.134)">
<title>流程.32</title>
<desc>获取心晓事件 长度、标签</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="70.87" height="42.5197"/>
<rect x="0" y="552.756" width="70.8661" height="42.5197" class="st1"/>
<text x="11.43" y="571.35" class="st9" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>获取心晓事件<v:newlineChar/><tspan
x="15.43" dy="1.331em" class="st3">长度</tspan>、标签</text> </g>
<g id="shape33-95" v:mID="33" v:groupContext="shape" v:layerMember="0" transform="translate(532.913,-314.646)">
<title>流程.33</title>
<desc>向前、向后 获取一分钟</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="70.87" height="42.5197"/>
<rect x="0" y="552.756" width="70.8661" height="42.5197" class="st1"/>
<text x="15.43" y="571.35" class="st9" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>向前、向后<v:newlineChar/><tspan
x="15.43" dy="1.331em" class="st3">获取一分钟</tspan></text> </g>
<g id="shape34-99" v:mID="34" v:groupContext="shape" v:layerMember="0" transform="translate(637.795,-314.646)">
<title>流程.34</title>
<desc>向前、向后 获取一分钟+与PSG信号长度差值/2</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="70.87" height="42.5197"/>
<rect x="0" y="552.756" width="70.8661" height="42.5197" class="st1"/>
<text x="15.43" y="566.03" class="st9" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>向前、向后<v:newlineChar/><tspan
x="3.01" dy="1.331em" class="st3">获取一分钟</tspan><tspan class="st4">+</tspan><tspan class="st4">PSG</tspan><tspan
x="7.86" dy="1.331em" class="st3">信号长度差值</tspan><tspan class="st4">/2</tspan></text> </g>
<g id="shape36-107" v:mID="36" v:groupContext="shape" v:layerMember="0" transform="translate(532.913,-250.157)">
<title>流程.36</title>
<desc>事件上色标注</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="70.87" height="42.5197"/>
<rect x="0" y="552.756" width="70.8661" height="42.5197" class="st1"/>
<text x="11.43" y="576.68" class="st9" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>事件上色标注</text> </g>
<g id="shape38-110" v:mID="38" v:groupContext="shape" v:layerMember="0" transform="translate(637.795,-250.157)">
<title>流程.38</title>
<desc>事件上色标注</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="70.87" height="42.5197"/>
<rect x="0" y="552.756" width="70.8661" height="42.5197" class="st1"/>
<text x="11.43" y="576.68" class="st9" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>事件上色标注</text> </g>
<g id="shape39-113" v:mID="39" v:groupContext="shape" v:layerMember="0" transform="translate(583.937,-185.669)">
<title>流程.39</title>
<desc>显示</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="70.87" height="42.5197"/>
<rect x="0" y="552.756" width="70.8661" height="42.5197" class="st1"/>
<text x="27.43" y="576.68" class="st9" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>显示</text> </g>
<g id="shape40-116" v:mID="40" v:groupContext="shape" v:layerMember="1" transform="translate(518.74,-508.11)">
<title>动态连接线.40</title>
<path d="M0 602.36 L62.52 602.36" class="st7"/>
</g>
<g id="shape41-121" v:mID="41" v:groupContext="shape" v:layerMember="1" transform="translate(627.874,-464.173)">
<title>动态连接线.41</title>
<path d="M0 595.28 L0 616.54 L-59.53 616.54 L-59.53 632.28" class="st7"/>
</g>
<g id="shape42-126" v:mID="42" v:groupContext="shape" v:layerMember="1" transform="translate(627.874,-464.173)">
<title>动态连接线.42</title>
<path d="M0 595.28 L0 616.54 L45.35 616.54 L45.35 632.28" class="st7"/>
</g>
<g id="shape43-131" v:mID="43" v:groupContext="shape" v:layerMember="1" transform="translate(561.26,-379.134)">
<title>动态连接线.43</title>
<path d="M7.09 595.28 L7.09 611.73" class="st7"/>
</g>
<g id="shape44-136" v:mID="44" v:groupContext="shape" v:layerMember="1" transform="translate(666.142,-379.134)">
<title>动态连接线.44</title>
<path d="M7.09 595.28 L7.09 611.73" class="st7"/>
</g>
<g id="shape45-141" v:mID="45" v:groupContext="shape" v:layerMember="1" transform="translate(666.142,-314.646)">
<title>动态连接线.45</title>
<path d="M7.09 595.28 L7.09 611.73" class="st7"/>
</g>
<g id="shape46-146" v:mID="46" v:groupContext="shape" v:layerMember="1" transform="translate(561.26,-314.646)">
<title>动态连接线.46</title>
<path d="M7.09 595.28 L7.09 611.73" class="st7"/>
</g>
<g id="shape47-151" v:mID="47" v:groupContext="shape" v:layerMember="1" transform="translate(568.346,-250.157)">
<title>动态连接线.47</title>
<path d="M0 595.28 L0 605.91 L51.02 605.91 L51.02 611.73" class="st7"/>
</g>
<g id="shape48-156" v:mID="48" v:groupContext="shape" v:layerMember="1" transform="translate(673.228,-250.157)">
<title>动态连接线.48</title>
<path d="M0 595.28 L0 605.91 L-53.86 605.91 L-53.86 611.73" class="st7"/>
</g>
<g id="shape49-161" v:mID="49" v:groupContext="shape" v:layerMember="1" transform="translate(668.976,-508.11)">
<title>动态连接线.49</title>
<path d="M0 602.36 L49.76 602.36" class="st7"/>
</g>
<g id="shape51-166" v:mID="51" v:groupContext="shape" v:layerMember="1" transform="translate(578.268,-206.929)">
<title>动态连接线.51</title>
<path d="M5.67 595.28 L-66.61 595.28 L-66.61 359.29 L-38.27 359.29 L-38.27 301.18 L2.99 301.18" class="st7"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -1,5 +1,5 @@
# -*- coding: cp936 -*-
# 使用gbk编码才能显示
# 使用gbk编码才能读标签
"""
@author:Marques
@file:Prepare_Data.py
@ -7,9 +7,9 @@
@email:2021022362@m.scnu.edu.cn
@time:2022/03/26
"""
from datetime import datetime
from typing import Union, List
import time
from typing import List
import logging
import pyedflib
from pathlib import Path
import numpy as np
@ -17,32 +17,53 @@ import pandas as pd
from matplotlib import pyplot as plt, gridspec
from Preprocessing import BCG_Operation
from tqdm import tqdm
from datetime import datetime
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# ['EEG F3-A2', 'EEG F4-A1', 'EEG C3-A2', 'EEG C4-A1', 'EEG O1-A2',
# 'EEG O2-A1', 'EOG Right', 'EOG Left', 'EMG Chin', 'ECG I', 'RR',
# 'ECG II', 'Effort Tho', 'Flow Patient', 'Flow Patient', 'Effort Abd',
# 'SpO2', 'Pleth', 'Snore', 'Body', 'Pulse', 'Leg LEG1', 'Leg LEG2',
# 'EEG A1-A2', 'Imp']
class Prepare_Data:
# 设置日志
logger = logging.getLogger()
logger.setLevel(logging.NOTSET)
realtime = time.strftime('%Y%m%d', time.localtime(time.time()))
fh = logging.FileHandler(Path("../history") / (realtime + ".log"), mode='a')
fh.setLevel(logging.NOTSET)
fh.setFormatter(logging.Formatter("%(asctime)s: %(message)s"))
logger.addHandler(fh)
ch = logging.StreamHandler()
ch.setLevel(logging.NOTSET)
ch.setFormatter(logging.Formatter("%(asctime)s: %(message)s"))
logger.addHandler(ch)
logging.getLogger('matplotlib.font_manager').disabled = True
logging.info("------------------------------------")
class Quality_Relabel:
# 可选择的通道
base_channel = ['EEG F3-A2', 'EEG F4-A1', 'EEG C3-A2', 'EEG C4-A1', 'EEG O1-A2', 'EEG O2-A1', 'EOG Right',
'EOG Left', 'EMG Chin', 'ECG I', 'RR', 'ECG II', 'Effort Tho', 'Flow Patient', 'Flow Patient', 'HR',
'Effort Abd', 'SpO2', 'Pleth', 'Snore', 'Body', 'Pulse', 'Leg LEG1', 'Leg LEG2', 'EEG A1-A2', 'Imp']
# 显示事件
base_event = ["Hypopnea", "Central apnea", "Obstructive apnea", "Mixed apnea"]
base_event = ["Hypopnea", "Central apnea", "Obstructive apnea", "Mixed apnea", "Desaturation"]
# 设定事件和其对应颜色
# 蓝色 背景
# 粉色 低通气
# 橙色 中枢性
# 红色 阻塞型 与 混合型
color_cycle = ["blue", "pink", "orange", "red", "red"]
# event_code color event
# 0 蓝色 背景
# 1 粉色 低通气
# 2 橙色 中枢性
# 3 红色 阻塞型
# 4 红色 混合型
# 5 绿色 血氧饱和度下降
color_cycle = ["blue", "pink", "orange", "red", "red", "green"]
assert len(color_cycle) == len(base_event) + 1, "基础事件数量与颜色数量不一致"
def __init__(self, sampNo: int, frequency: int = 100, bcg_frequency: int = 1000,
@ -67,6 +88,7 @@ class Prepare_Data:
# 用来显示颜色时按点匹配事件
self.ecg_event_label = None
self.bcg_event_label = None
self.spo2_event_label = None
# 仅包含关注暂停事件的列表
self.ecg_event_label_filtered_df = None
@ -86,7 +108,7 @@ class Prepare_Data:
def check_channel(self):
for i in self.channel_list:
if i not in self.base_channel:
print(f"{i} 不存在于常见通道名中")
logging.debug(f"{i} 不存在于常见通道名中")
print(f"常见通道名:{self.channel_list}")
def read_data(self, frequency: int = 100, bcg_frequency: int = 1000):
@ -94,29 +116,32 @@ class Prepare_Data:
ecg_path = Path(f"../Data/ECG/A{str(self.sampNo).rjust(7, '0')}.edf")
if not bcg_path.exists():
logging.error(f"{bcg_path} 不存在!")
raise FileNotFoundError(f"{bcg_path} 不存在!")
if not ecg_path.exists():
logging.error(f"{ecg_path} 不存在!")
raise FileNotFoundError(f"{ecg_path} 不存在!")
with pyedflib.EdfReader(str(ecg_path.resolve())) as file:
signal_num = file.signals_in_file
print(f"{self.sampNo} EDF file signal number is {signal_num}")
logging.debug(f"{self.sampNo} EDF file signal number is {signal_num}")
signal_label = file.getSignalLabels()
print(f"{self.sampNo} EDF file signal label : {signal_label}")
logging.debug(f"{self.sampNo} EDF file signal label : {signal_label}")
self.ecg_start_time = file.getStartdatetime()
# 根据PSG记录长度生成事件表
self.ecg_event_label = np.zeros(file.getFileDuration() * self.frequency)
self.spo2_event_label = np.zeros(file.getFileDuration() * self.frequency)
# 打印PSG信息
file.file_info_long()
# sub_index 用于区分两个flow patient
sub_index = 1
logging.info("读取PSG信号····")
for i, index in enumerate(signal_label):
# 仅加载选中的通道
if index in self.channel_list:
@ -124,7 +149,6 @@ class Prepare_Data:
if index == 'Flow Patient':
index = index + str(sub_index)
sub_index += 1
signal = file.readSignal(i)
sample_frequency = file.getSampleFrequency(i)
# 读取采样率 进行重采样
@ -133,8 +157,10 @@ class Prepare_Data:
elif sample_frequency > frequency:
signal = signal[::int(sample_frequency / frequency)]
self.signal_select[index] = signal
logging.info(f"完成读取PSG: {index}")
# 加载心晓信号
logging.info("读取心晓信号····")
signal = np.load(bcg_path)
preprocessing = BCG_Operation(sample_rate=bcg_frequency)
# 20Hz低通去噪
@ -156,21 +182,24 @@ class Prepare_Data:
ecg_label_path = Path(f"../Data/ECG_label/export{self.sampNo}.csv")
if not bcg_label_path.exists():
logging.error(f"{bcg_label_path} 不存在!")
raise FileNotFoundError(f"{bcg_label_path} 不存在!")
if not ecg_label_path.exists():
logging.error(f"{ecg_label_path} 不存在!")
raise FileNotFoundError(f"{ecg_label_path} 不存在!")
df = pd.read_csv(ecg_label_path, encoding='gbk')
self.ecg_event_label_df = df
# 过滤不关注的事件
df = df[df["Event type"].isin(self.focus_event_list)]
df2 = df[df["Event type"].isin(self.focus_event_list)]
# 根据epoch进行排列方便索引
df = df.sort_values(by='Epoch')
self.ecg_event_label_filtered_df = df
df2 = df2.sort_values(by='Epoch')
self.ecg_event_label_filtered_df = df2
for one_data in df.index:
logging.info("遍历PSG事件···")
for one_data in tqdm(df.index, ncols=80):
one_data = df.loc[one_data]
# 通过开始事件推算事件起始点与结束点
@ -190,6 +219,8 @@ class Prepare_Data:
self.ecg_event_label[SP:EP] = 3
elif one_data["Event type"] == "Mixed apnea":
self.ecg_event_label[SP:EP] = 4
elif one_data["Event type"] == "Desaturation":
self.spo2_event_label[SP:EP] = 5
# 读取心晓事件
df = pd.read_csv(bcg_label_path, encoding='gbk')
@ -198,11 +229,11 @@ class Prepare_Data:
self.bcg_event_label_df = df
# 过滤不关注事件
df = df[df["Event type"].isin(self.focus_event_list)]
df = df.sort_values(by='Epoch')
self.bcg_event_label_filtered_df = df
for one_data in df.index:
df2 = df[df["Event type"].isin(self.focus_event_list)]
df2 = df2.sort_values(by='Epoch')
self.bcg_event_label_filtered_df = df2
logging.info("遍历心晓事件···")
for one_data in tqdm(df.index):
one_data = df.loc[one_data]
SP = one_data["new_start"] * self.frequency
EP = one_data["new_end"] * self.frequency
@ -221,17 +252,19 @@ class Prepare_Data:
# 心晓事件数量{len(self.bcg_event_label_filtered_df)}"
def show_one_event(self, bcg_index: int, ecg_index: int, front_add_second: int = 60,
back_add_second: int = 60, main_SA_visual: int = 1):
back_add_second: int = 60):
"""
:param bcg_index: 心晓事件在csv中行号
:param ecg_index: PSG事件在csv中序号
:param front_add_second: 向前延伸时间
:param back_add_second: 向后延伸时间
:param main_SA_visual: 1仅当前事件上色 0不上色 2所有事件上色
:return:
"""
one_bcg_data = self.bcg_event_label_df.loc[bcg_index]
one_ecg_data = self.ecg_event_label_df.loc[ecg_index]
# 获取事件实际在csv文件中的序号
bcg_real_index = self.bcg_event_label_filtered_df.index[bcg_index],
ecg_real_index = self.ecg_event_label_filtered_df.index[ecg_index],
one_bcg_data = self.bcg_event_label_df.loc[bcg_real_index]
one_ecg_data = self.ecg_event_label_df.loc[ecg_real_index]
# 获取ECG事件开始与结束时间
event_start_time = datetime.strptime(one_ecg_data["Date"] + " " + one_ecg_data["Time"], '%Y/%m/%d %H:%M:%S')
@ -243,7 +276,16 @@ class Prepare_Data:
bcg_SP = one_bcg_data["new_start"]
bcg_EP = one_bcg_data["new_end"]
bcg_duration = int(float(str(one_bcg_data["Duration"]).split("(")[0]))
print(ecg_SP, ecg_EP, bcg_SP, bcg_EP)
logging.info(f"sampNo:{self.sampNo} "
f"bcg[index:{bcg_index} epoch:{one_bcg_data['Epoch']} event:{one_bcg_data['Event type']}] "
f"ecg:[index:{ecg_index} epoch:{one_ecg_data['Epoch']} event:{one_ecg_data['Event type']}]")
if one_bcg_data['Event type'] != one_ecg_data['Event type']:
logging.error(f"sampNo:{self.sampNo} PSG事件与心晓时间不一致请排查"
f"bcg[index:{bcg_index} epoch:{one_bcg_data['Epoch']} event:{one_bcg_data['Event type']}] "
f"ecg:[index:{ecg_index} epoch:{one_ecg_data['Epoch']} event:{one_ecg_data['Event type']}]")
raise ValueError()
# 进行向两边延展
ecg_SP = ecg_SP - front_add_second
@ -253,158 +295,99 @@ class Prepare_Data:
# 绘图
plt.figure(figsize=(12, 6), dpi=150)
gs = gridspec.GridSpec(7, 1, height_ratios=[1, 1, 1, 3, 1, 1, 1])
# 各个子图之间的比例
gs = gridspec.GridSpec(7, 1, height_ratios=[1, 1, 1, 1, 1, 3, 1])
plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
plt.margins(0, 0)
plt.tight_layout()
# 绘制 Flow1
plt.subplot(gs[0])
# ['Effort Tho', 'Effort Abd', 'SpO2', 'Flow Patient', 'Flow Patient']
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency),
self.signal_select["Effort Tho"][ecg_SP * self.frequency:ecg_EP * self.frequency], label="Effort Tho")
# 进行事件颜色标注
for j in range(1, 5):
mask = self.ecg_event_label[ecg_SP * self.frequency:ecg_EP * self.frequency] == j
y = (self.signal_select["Effort Tho"][ecg_SP * self.frequency:ecg_EP * self.frequency] * mask).astype(
'float')
np.place(y, y == 0, np.nan)
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency), y, color=self.color_cycle[j])
# 显示图注
plt.legend(loc=1)
# 隐藏部分边框
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
# 去掉x轴
plt.xticks([])
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="Flow Patient1")
# 绘制 Flow2
plt.subplot(gs[1])
# ['Effort Tho', 'Effort Abd', 'SpO2', 'Flow Patient', 'Flow Patient']
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency),
self.signal_select["Effort Abd"][ecg_SP * self.frequency:ecg_EP * self.frequency], label="Effort Abd")
for j in range(1, 5):
mask = self.ecg_event_label[ecg_SP * self.frequency:ecg_EP * self.frequency] == j
y = (self.signal_select["Effort Abd"][ecg_SP * self.frequency:ecg_EP * self.frequency] * mask).astype(
'float')
np.place(y, y == 0, np.nan)
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency), y, color=self.color_cycle[j])
plt.title(f"sampNo:{self.sampNo} Epoch:{one_ecg_data['Epoch']} Duration:{one_ecg_data['Duration']}")
plt.legend(loc=1)
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
plt.xticks([])
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="Flow Patient2",
title=f"PSG sampNo:{self.sampNo} Epoch:{one_ecg_data['Epoch']} Duration:{one_ecg_data['Duration']}")
plt.subplot(gs[2])
# ['Effort Tho', 'Effort Abd', 'SpO2', 'Flow Patient', 'Flow Patient']
plt.plot(np.linspace(bcg_SP, bcg_EP, (bcg_EP - bcg_SP) * self.frequency),
self.signal_select["xin_xiao_respire"][bcg_SP * self.frequency:bcg_EP * self.frequency], label="心晓 呼吸")
min_bcg = self.signal_select["xin_xiao_respire"][bcg_SP * self.frequency:bcg_EP * self.frequency].min()
len_bcg = bcg_EP * self.frequency - bcg_SP * self.frequency
for j in range(1, 5):
mask = self.bcg_event_label[bcg_SP * self.frequency:bcg_EP * self.frequency] == j
y = (min_bcg.repeat(len_bcg) * mask).astype('float')
np.place(y, y == 0, np.nan)
plt.plot(np.linspace(bcg_SP, bcg_EP, (bcg_EP - bcg_SP) * self.frequency), y, color=self.color_cycle[j])
# plt.title(f"sampNo:{self.sampNo} Epoch:{one_bcg_data['Epoch']} Duration:{one_bcg_data['Duration']}")
plt.legend(loc=1)
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
plt.xticks([])
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="Effort Tho")
plt.subplot(gs[3])
# ['Effort Tho', 'Effort Abd', 'SpO2', 'Flow Patient', 'Flow Patient']
plt.plot(np.linspace(bcg_SP, bcg_EP, (bcg_EP - bcg_SP) * self.frequency),
self.signal_select["xin_xiao"][bcg_SP * self.frequency:bcg_EP * self.frequency], label="心晓")
min_bcg = self.signal_select["xin_xiao"][bcg_SP * self.frequency:bcg_EP * self.frequency].min()
len_bcg = bcg_EP * self.frequency - bcg_SP * self.frequency
for j in range(1, 5):
mask = self.bcg_event_label[bcg_SP * self.frequency:bcg_EP * self.frequency] == j
y = (min_bcg.repeat(len_bcg) * mask).astype('float')
np.place(y, y == 0, np.nan)
plt.plot(np.linspace(bcg_SP, bcg_EP, (bcg_EP - bcg_SP) * self.frequency), y, color=self.color_cycle[j])
plt.title(f"sampNo:{self.sampNo} Epoch:{one_bcg_data['Epoch']} Duration:{one_bcg_data['Duration']}")
plt.legend(loc=1)
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
plt.xticks([]) # 去掉x轴
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="Effort Abd")
plt.subplot(gs[4])
# ['Effort Tho', 'Effort Abd', 'SpO2', 'Flow Patient', 'Flow Patient']
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency),
self.signal_select["Flow Patient1"][ecg_SP * self.frequency:ecg_EP * self.frequency],
label="Flow Patient1")
for j in range(1, 5):
mask = self.ecg_event_label[ecg_SP * self.frequency:ecg_EP * self.frequency] == j
y = (self.signal_select["Flow Patient1"][ecg_SP * self.frequency:ecg_EP * self.frequency] * mask).astype(
'float')
np.place(y, y == 0, np.nan)
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency), y, color=self.color_cycle[j])
plt.legend(loc=1)
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
plt.xticks([]) # 去掉x轴
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="SpO2", event_code=[5])
plt.subplot(gs[5])
# ['Effort Tho', 'Effort Abd', 'SpO2', 'Flow Patient', 'Flow Patient']
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency),
self.signal_select["Flow Patient2"][ecg_SP * self.frequency:ecg_EP * self.frequency],
label="Flow Patient2")
for j in range(1, 5):
mask = self.ecg_event_label[ecg_SP * self.frequency:ecg_EP * self.frequency] == j
y = (self.signal_select["Flow Patient2"][ecg_SP * self.frequency:ecg_EP * self.frequency] * mask).astype(
'float')
np.place(y, y == 0, np.nan)
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency), y, color=self.color_cycle[j])
plt.legend(loc=1)
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
plt.xticks([])
self.plt_channel(plt_=plt, SP=bcg_SP, EP=bcg_EP, channel="xin_xiao", event_show_under=True)
plt.subplot(gs[6])
# ['Effort Tho', 'Effort Abd', 'SpO2', 'Flow Patient', 'Flow Patient']
plt.plot(np.linspace(ecg_SP, ecg_EP, (ecg_EP - ecg_SP) * self.frequency),
self.signal_select["SpO2"][ecg_SP * self.frequency:ecg_EP * self.frequency], label="SpO2")
plt.legend(loc=1)
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
plt.xticks([])
self.plt_channel(plt_=plt, SP=bcg_SP, EP=bcg_EP, channel="xin_xiao_respire", event_show_under=True,
ax_bottom=True,
title=f"心晓 sampNo:{self.sampNo} Epoch:{one_bcg_data['Epoch']} Duration:{one_bcg_data['Duration']}",
)
plt.show()
def show_all_event(self, start_index: int = 0, shifting: int = 0, front_add_second: int = 60,
back_add_second: int = 60, main_SA_visual: int = 1):
def plt_channel(self, plt_, SP, EP, channel, event_code=[1, 2, 3, 4], event_show_under=False,
ax_top=False, ax_bottom=False, ax_left=True, ax_right=False, title=None):
"""
for index in range(start_index, len(self.bcg_event_label_filtered_df)):
self.show_one_event(self.bcg_event_label_filtered_df.index[index],
self.ecg_event_label_filtered_df.index[index + shifting],
:param plt_:
:param SP: 显示开始秒数
:param EP: 显示结束秒数
:param channel: 通道名称
:param event_code: 要上色的事件编号
:param event_show_under: 事件颜色显示在信号下面
:param ax_top: 显示上框线
:param ax_bottom: 显示下框线
:param ax_left: 显示左框线
:param ax_right: 显示右框线
:param title: 显示标题
:return:
"""
plt_.plot(np.linspace(SP, EP, (EP - SP) * self.frequency),
self.signal_select[channel][SP * self.frequency:EP * self.frequency], label=channel)
for j in event_code:
if channel == "SpO2":
mask = self.spo2_event_label[SP * self.frequency:EP * self.frequency] == j
else:
mask = self.ecg_event_label[SP * self.frequency:EP * self.frequency] == j
if event_show_under:
min_point = self.signal_select[channel][SP * self.frequency:EP * self.frequency].min()
len_segment = EP * self.frequency - SP * self.frequency
y = (min_point.repeat(len_segment) * mask).astype('float')
np.place(y, y == 0, np.nan)
else:
y = (self.signal_select[channel][SP * self.frequency:EP * self.frequency] * mask).astype('float')
np.place(y, y == 0, np.nan)
plt_.plot(np.linspace(SP, EP, (EP - SP) * self.frequency), y, color=self.color_cycle[j])
plt_.legend(loc=1)
if title is not None:
plt_.title(title)
ax = plt.gca()
ax.spines["top"].set_visible(ax_top)
ax.spines["right"].set_visible(ax_right)
ax.spines["bottom"].set_visible(ax_bottom)
ax.spines["left"].set_visible(ax_left)
# xticks = [[]] if xticks else [range(SP, EP, 5), [str(i) for i in range(0, (EP - SP), 5)]]
# print(xticks)
# plt_.xticks(*xticks) # 去掉x轴
def show_all_event(self, start_bcg_index: int = 0, shifting: int = 0, front_add_second: int = 60,
back_add_second: int = 60):
for index in range(start_bcg_index, len(self.bcg_event_label_filtered_df)):
self.show_one_event(index,
index + shifting,
front_add_second=front_add_second,
back_add_second=back_add_second,
main_SA_visual=main_SA_visual
back_add_second=back_add_second
)
def get_fft(self):
pass
if __name__ == '__main__':
prepareData = Prepare_Data(670)
prepareData = Quality_Relabel(670)
prepareData.show_all_event()