- Created a new module `utils/__init__.py` to consolidate utility imports. - Added `event_map.py` for mapping apnea event types to numerical values and colors. - Implemented various filtering functions in `filter_func.py`, including Butterworth, Bessel, downsampling, and notch filters. - Developed `operation_tools.py` for dataset configuration loading, event mask generation, and signal processing utilities. - Introduced `split_method.py` for segmenting data based on movement and amplitude criteria. - Added `statistics_metrics.py` for calculating amplitude metrics and generating confusion matrices. - Included a new Excel file for additional data storage.
14 KiB
项目背景文档(供 Agent 快速上手)
1. 文档目的
这份文档用于帮助新进入仓库的 agent 快速建立项目心智模型,重点回答下面几个问题:
- 这个仓库在做什么
- 核心处理链路是什么
- 代码从哪里开始看
- 输入数据长什么样,输出产物长什么样
- 哪些模块已经可用,哪些模块还只是占位或半成品
2. 一句话理解项目
DataPrepare 是一个睡眠呼吸暂停数据预处理仓库,主要用于把原始的 BCG / PSG 信号与呼吸暂停标签整理成可训练的数据集。
当前主线可以概括为两步:
- 在
event_mask_process/中把原始标注和规则检测结果整理成逐秒标签掩码。 - 在
dataset_builder/中根据这些掩码切出固定长度窗口,并将信号和窗口索引保存为npz数据集。
3. 仓库总览
| 目录 | 作用 | 备注 |
|---|---|---|
dataset_config/ |
各数据集的 YAML 配置 | 包含路径、采样率、阈值、切窗参数 |
event_mask_process/ |
生成逐秒标签掩码 | 主入口之一 |
dataset_builder/ |
将信号切成窗口并保存数据集 | 主入口之二 |
signal_method/ |
信号预处理、规则检测、特征计算 | 规则逻辑核心 |
utils/ |
读文件、标签转换、切窗、滤波、通用工具 | 底层支撑 |
draw_tools/ |
全夜信号图、分段图、统计图 | 调试与可视化 |
dataset_tools/ |
辅助脚本 | 包括配对拷贝、SHHS 标注检查 |
output/ |
中间结果样例 | 仓库内已有若干处理结果示例 |
4. 项目主线流程
4.1 HYS(BCG 主线)
对应文件:
event_mask_process/HYS_process.pydataset_builder/HYS_dataset.py
处理过程:
- 从
root_path/OrgBCG_Aligned/<id>/OrgBCG_Sync_*.txt读取原始 BCG 同步信号。 - 从
root_path/Label/<id>/SA Label_corrected.csv读取人工修正后的呼吸暂停标签。 - 对原始 BCG 进行 50Hz 陷波,再拆出:
- 呼吸分量
resp_data - BCG 分量
bcg_data
- 呼吸分量
- 根据配置做规则检测,生成逐秒掩码:
Resp_LowAmp_LabelResp_Movement_LabelResp_AmpChange_LabelBCG_LowAmp_LabelBCG_Movement_LabelBCG_AmpChange_LabelDisable_Label(来自排除区间.xlsx)SA_Label/SA_Score(来自人工标签)
- 将这些结果保存为
output/HYS/<id>/<id>_Processed_Labels.csv。 - 在数据集构建阶段读取上述逐秒标签,按
window_sec和stride_sec切成窗口。 - 保存处理后的信号
Signals/*.npz、窗口索引Segments_List/*.npz、标签副本Labels/*.csv。
4.2 HYS_PSG(PSG 主线)
对应文件:
event_mask_process/HYS_PSG_process.pydataset_builder/HYS_PSG_dataset.py
处理过程:
- 从
root_path/PSG_Aligned/<id>/读取 PSG 通道,包括:RpeakECG_SyncEffort ThoEffort AbdFlow PFlow TSpO25_class
- 从同目录读取
SA Label_Sync.csv。 - 在
HYS_PSG_process.py中生成较简化的逐秒标签:SA_LabelSA_ScoreDisable_Label(主要由睡眠分期里的清醒期生成)- 其余
Resp_*/BCG_*掩码目前全部置零
- 在
HYS_PSG_dataset.py中对胸腹带、流量、SpO2、RRI 做统一重采样与长度对齐。 - 对 SpO2 进行异常填补或置空,再切成窗口,保存为 PSG 数据集。
4.3 设计上的共性
无论是 HYS 还是 HYS_PSG,核心设计都是:
- 先把整夜记录整理成逐秒掩码。
- 再根据掩码和切窗规则提取训练片段。
这意味着以后如果要改“可用性判断”或“切窗逻辑”,优先看:
event_mask_process/utils/split_method.py
5. 数据与目录约定
5.1 外部数据目录
这个仓库本身不包含原始数据,真正的数据目录由 YAML 中的绝对路径指定,例如:
/mnt/disk_wd/marques_dataset/DataCombine2023/HYS/mnt/disk_wd/marques_dataset/shhs/polysomnography/shhs1
因此在新环境运行时,第一件事通常不是改代码,而是先改 dataset_config/*.yaml 里的绝对路径。
5.2 HYS 数据目录约定
代码默认外部目录至少包含:
OrgBCG_Aligned/<id>/OrgBCG_Sync_<fs>.txtPSG_Aligned/<id>/...Label/<id>/SA Label_corrected.csv
5.3 HYS_PSG 数据目录约定
代码默认 PSG_Aligned/<id>/ 内文件命名符合下面的模式:
Rpeak*.txtECG_Sync*.txtEffort Tho*.txtEffort Abd*.txtFlow P*.txtFlow T*.txtSpO2*.txt5_class*.txtSA Label_Sync.csv
5.4 处理中间结果目录
仓库内 output/ 保存的是“中间标签与图像结果”,不是最终训练数据集。
最终数据集通常会写到 YAML 中 dataset_save_path 指向的外部目录。
6. 核心入口脚本
6.1 主入口
| 场景 | 脚本 |
|---|---|
| HYS 逐秒标签生成 | event_mask_process/HYS_process.py |
| HYS 数据集构建 | dataset_builder/HYS_dataset.py |
| HYS_PSG 逐秒标签生成 | event_mask_process/HYS_PSG_process.py |
| HYS_PSG 数据集构建 | dataset_builder/HYS_PSG_dataset.py |
6.2 辅助脚本
| 脚本 | 作用 |
|---|---|
dataset_tools/resp_pair_copy.py |
将 HYS/ZD5Y 的 BCG 与 PSG 原始文件拷贝为配对数据集 |
dataset_tools/shhs_annotations_check.py |
统计 SHHS XML 标注中的事件类型组合 |
event_mask_process/SHHS1_process.py |
SHHS1 处理入口占位,目前未实现 |
6.3 入口脚本的共同特点
- 大多数脚本没有命令行参数接口。
- 配置文件路径通常直接写在
if __name__ == '__main__':中。 - 运行逻辑依赖 YAML 中的绝对路径。
所以如果 agent 要“跑脚本”,通常需要先确认:
- 当前机器是否存在对应外部数据目录。
- YAML 路径是否匹配当前环境。
7. 关键模块说明
7.1 utils/
utils/HYS_FileReader.py
负责各种输入文件读取,是仓库最重要的底层模块之一:
read_signal_txt:读取单通道 txt,并根据文件名中的采样率推断fsread_label_csv:读取人工修正的 HYS 标签read_raw_psg_label:读取 PSG 原始同步标签read_disable_excel:读取排除区间.xlsxread_mask_execl:读取处理后的逐秒标签 CSV,并生成事件片段列表read_psg_channel:按通道名读取 PSG 文件夹里的多通道数据
utils/operation_tools.py
负责标签转换、片段提取和通用处理:
load_dataset_conf:读取 YAMLgenerate_event_mask:把事件表转换成逐秒SA_Labelgenerate_disable_mask:把 Excel 中的排除区间转换成逐秒Disable_Labelevent_mask_2_list:把 0/1 掩码转为[start, end]列表merge_short_gaps/remove_short_durations:对逐秒掩码做时长后处理fill_spo2_anomaly:修补 SpO2 异常段
utils/split_method.py
真正的切窗规则在这里:
- 默认按
window_sec/stride_sec滑窗 - 只在
EnableSegment内生成可用窗口 - 如果一个窗口中
Resp_Movement_Label | Resp_LowAmp_Label超过窗口时长的 2/3,则该窗口转入disable_segment_list
utils/filter_func.py
提供滤波和采样率处理:
- Butterworth / Bessel
- 陷波
- 整数倍降采样
- 自动升降采样
- 移动平均去趋势
7.2 signal_method/
signal_method/signal_process.py
负责信号预处理:
signal_filter_split:把原始 OrgBCG 信号拆成呼吸分量和 BCG 分量psg_effort_filter:处理 PSG 努力带 / 流量信号rpeak2hr/rpeak2rri_interpolation:由 R 峰生成 HR / RRI
signal_method/rule_base_event.py
规则检测主逻辑:
detect_movement:基于滑窗标准差和局部幅值比较检测体动movement_revise:对体动掩码做二次修正detect_low_amplitude_signal:检测低幅值position_based_sleep_recognition_v2/v3:根据体动前后幅值变化标记姿势/幅值变化段
signal_method/normalize_method.py
normalize_resp_signal_by_segment 会按“可用片段”做分段 z-score 标准化。
HYS 中通常按 Resp_AmpChange_Label 的反向片段来归一化,目的是减少整夜幅值漂移带来的影响。
7.3 draw_tools/
主要用于人工检查处理质量:
draw_signal_with_mask:画 HYS 全夜原始信号 + 规则掩码draw_psg_signal:画 HYS_PSG 全夜 PSG 信号draw_psg_label/draw_psg_bcg_label:按窗口导出分段图
7.4 dataset_builder/
核心职责是把“整夜记录 + 逐秒掩码”转换成训练样本:
- 保存处理后的多通道信号到
npz - 保存窗口起止列表到
npz - 把标签 CSV 一并拷贝到数据集目录
8. 标签、通道和编码约定
8.1 呼吸暂停事件编码
定义于 utils/event_map.py:
| 事件 | 编码 |
|---|---|
Hypopnea |
1 |
Central apnea |
2 |
Obstructive apnea |
3 |
Mixed apnea |
4 |
8.2 PSG 通道编号映射
同样定义于 utils/event_map.py:
| 编号 | 通道名 |
|---|---|
| 1 | Rpeak |
| 2 | ECG_Sync |
| 3 | Effort Tho |
| 4 | Effort Abd |
| 5 | Flow P |
| 6 | Flow T |
| 7 | SpO2 |
| 8 | 5_class |
8.3 睡眠分期编码
5_class 在读取时会转成整数:
| 分期 | 编码 |
|---|---|
N3 |
1 |
N2 |
2 |
N1 |
3 |
R |
4 |
W |
5 |
8.4 逐秒标签 CSV 字段
Processed_Labels.csv 的核心字段为:
SecondSA_LabelSA_ScoreDisable_LabelResp_LowAmp_LabelResp_Movement_LabelResp_AmpChange_LabelBCG_LowAmp_LabelBCG_Movement_LabelBCG_AmpChange_Label
样例可见仓库内:
output/HYS/220/220_Processed_Labels.csvoutput/HYS_PSG/220/220_Processed_Labels.csv
9. 主要配置文件
9.1 HYS
dataset_config/HYS_config.yaml 主要控制:
- 样本 ID 列表
- 原始数据根目录
- 中间标签保存目录
- 呼吸 / BCG 的滤波和降采样参数
- 低幅值、体动、幅值变化检测阈值
- 数据集窗口长度和步长
9.2 HYS_PSG
dataset_config/HYS_PSG_config.yaml 主要控制:
- 样本 ID 列表
- 目标统一采样率
target_fs - 努力带 / 流量滤波参数
- SpO2 异常填补参数
- 数据集输出路径
9.3 其他配置
dataset_config/ZD5Y_config.yaml:另一套 BCG 规则配置dataset_config/SHHS1_config.yaml:SHHS1 预留配置dataset_config/RESP_PAIR_HYS_config.yaml:HYS 配对原始数据拷贝dataset_config/RESP_PAIR_ZD5Y_config.yaml:ZD5Y 配对原始数据拷贝
10. 输出产物说明
10.1 中间输出
典型位置:
output/HYS/<id>/<id>_Processed_Labels.csvoutput/HYS/<id>/<id>_Signal_Plots.pngoutput/HYS_PSG/<id>/<id>_Processed_Labels.csvoutput/HYS_PSG/<id>/<id>_Signal_Plots.pngoutput/HYS_PSG/<id>/<id>_Signal_Plots_fill.png
10.2 最终数据集输出
由 dataset_builder/* 保存到 YAML 指定的外部目录,结构通常是:
Signals/Segments_List/Labels/
HYS 的 Signals/*.npz 里主要保存:
bcg_signal_notchbcg_signalresp_signal
HYS_PSG 的 Signals/*.npz 里主要保存:
Effort ThoEffort AbdEffortFlow PFlow TSpO2HRRRI5_class
Segments_List/*.npz 中主要保存:
segment_listdisable_segment_list
11. 推荐阅读顺序
如果 agent 是第一次接触这个仓库,建议按下面顺序阅读:
dataset_config/HYS_config.yamlevent_mask_process/HYS_process.pyutils/operation_tools.pyutils/split_method.pydataset_builder/HYS_dataset.pysignal_method/signal_process.pysignal_method/rule_base_event.pyutils/HYS_FileReader.py
如果要看 PSG 主线,再继续读:
dataset_config/HYS_PSG_config.yamlevent_mask_process/HYS_PSG_process.pydataset_builder/HYS_PSG_dataset.pydraw_tools/draw_label.py
12. 常见修改入口
如果你要改不同类型的问题,可以优先从这些文件入手:
| 需求 | 优先看哪里 |
|---|---|
| 调整阈值、采样率、窗口长度 | dataset_config/*.yaml |
| 修改逐秒标签生成逻辑 | event_mask_process/*.py |
| 修改体动 / 低幅值 / 幅值变化规则 | signal_method/rule_base_event.py |
| 修改滤波与重采样 | signal_method/signal_process.py、utils/filter_func.py |
| 修改切窗规则 | utils/split_method.py |
| 修改输入文件解析 | utils/HYS_FileReader.py |
| 修改事件编码或通道映射 | utils/event_map.py |
| 修改图像输出样式 | draw_tools/*.py |
13. 当前实现状态与注意事项
下面这些点对 agent 很重要:
- 仓库没有依赖清单文件(如
requirements.txt/pyproject.toml),依赖需要从源码导入中反推,当前至少涉及numpy、pandas、scipy、matplotlib、seaborn、yaml、tqdm、rich、polars、lxml、mne。 - 大部分脚本依赖绝对路径,迁移环境时优先修改 YAML。
event_mask_process/SHHS1_process.py目前基本为空,占位多于实现。event_mask_process/HYS_PSG_process.py当前是“简化版标签生成”,核心只用了 SA 标签和睡眠分期,Resp_*/BCG_*掩码还没有真正实现。dataset_builder/HYS_dataset.py里虽然保留了分段可视化入口,但实际绘图调用被注释掉了,因此默认不会导出分段图。utils/signal_process.py和utils/filter_func.py有部分重复实现;当前实际被utils/__init__.py导出并广泛使用的是filter_func.py中的版本。README.md目前非常简略,真正的项目逻辑主要还是要靠源码理解。
14. 对 Agent 最有价值的结论
如果只能记住几件事,请记住下面这些:
- 这是一个“先做逐秒掩码,再做固定窗口切片”的数据准备仓库。
- HYS 主线比 HYS_PSG 更完整,规则检测主要服务于 HYS。
- 切窗逻辑集中在
utils/split_method.py,不是分散在各个 builder 里。 - 原始数据不在仓库里,仓库只是代码和部分中间结果样例。
- 大多数运行问题都不是代码逻辑错,而是路径、文件命名、采样率和外部数据结构不匹配。