Files
CADx-4/research-wiki/任务书/04-核对包改成医生读得懂.md

205 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 任务书 04:核对包改成医生读得懂;资料库超声一路只留给 agent 的参数
## 目标
任务书 03 做出来的核对包(`runs/review_pack/20261017-060427-c7373ef-dirty/`)是照任务书做的,但任务书本身写错了读者:它把我们自己才用得上的东西(检查编号、字段名、原因码、tic.json 全部字段)都要求给了医生。本任务做三件事:
1. 资料库超声一路的 `tic.json` 只留「给 agent 的参数」,8 张图并进一个文件夹;
2. CEUS 对紫圈也算灌注指标,重跑;
3. 核对包改成合作医生拿到就能看懂的样子,医生看到的参数就是资料库里 agent 看到的那份。
医生不是搞计算机的。包里的每个文件、每一列、每一句话,都要回答得了「医生看这个能判断什么」;回答不了的不放。
来源:负责人 2026-10-17「说明.pdf 写的很奇怪,既不符合对于合作方的语气,我们是合作者啊……类似公文……合作方是医生,感觉他们也不一定看得懂」「TIC结果.csv 为什么有那么多值是空的」「中间结果……不需要给医生,他们又不是搞计算机的」「医生明确说需要有『给 agent 的参数』」「从 Lognormal 拟合曲线算出来,算不出来就是空;应该是要算两组的,一个是实质的曲线算,一个是去暗区的那条……得类似正常区域与疾病区域对比看。但是病灶整体肯定是不要的……每一组都是那些参数」「就用那几个指标」(指旧项目已经写程序算过的那组灌注指标);资料库借这次一起清理、8 张图放一个文件夹(负责人 2026-10-17 认可讨论会话的提议:「还没开始,你改任务书吧」)。
## 定下来的「给 agent 的参数」
- **两组**:胰腺实质(医生画的紫圈,`roi_pan`)一组,病灶去暗区(`roi_perf`)一组。病灶整体(`roi_all`)不要。
- **每组同样的参数**:旧项目 `perfusion_metrics.py` 那 11 个灌注指标,本仓库已迁移为 `src/cadx/ceus/_perfusion_metrics.py`:PE、TTP、WiR、RT、WiAUC、WiPI、WoR、FT、WoAUC、WiWoAUC、mTTl。辅助时刻 TI、TO、mTT 不给(它们只是算上面几项的中间量)。
- **怎么算**:照现在的做法,从过了质量门的 Lognormal 拟合曲线算;这一组拟合没过,整组为空;观测不够算不出的单项为空,不外推。
- **不给**:拟合成功与否、R²、背景圆、病灶整体、紫圈是否可用、关键帧未取到的原因、信号域等内部标记。
## 一、CEUS:指标改为对病灶去暗区和紫圈两组算
现在第 9 步对 `LESION_CURVES = ("roi_all", "roi_perf")` 算指标(`src/cadx/ceus/_pipeline.py:59`、`:313`),紫圈没算。改为只对 `roi_perf` 和 `roi_pan` 算;`roi_all` 的指标没有使用者了,同一次删掉。
注意 `LESION_CURVES` 同时决定「两条病灶曲线都过才定位 D1–D4」(`_pipeline.py:300`),那条规则不动;给「算指标的曲线」单独一个名字,不要改 `LESION_CURVES`。
`summary.json` 的 `perfusion_metrics` 下的键相应变为 `roi_perf`、`roi_pan`。
### 重跑
紫圈指标要重跑 CEUS 才有,顺便把 `-dirty` 的问题一起解决:
1. **开跑前工作区必须干净**(`git status` 无改动,包括负责人自己的 AGENTS.md、README.md、`research-wiki/paper/`)。不干净就停下来告诉负责人,不要替他提交。
2. 全量重跑 `ceus_quant`(40 例),再用新运行重新 `build`,再出核对包。三个运行目录都不带 `-dirty`。
3. 上次全量跑过一次 OOM(`runs/ceus/20261016-070216-e165b32-dirty.partial`),这次用当时修好后的设置。超过一分钟的命令放 tmux,日志写文件。
4. 报告里对比新旧两次 CEUS 运行:成功例数、各曲线拟合成功例数、各槽位定位例数应完全相同(只有指标换了曲线);不同就停下来查原因,不要往下走。
## 二、资料库:超声一路只留给 agent 的东西
资料库的定义是「专家能看到什么」,可见范围只在 build 一处决定。多余的值放进去、等 agent 那边再挑,就成了两处决定,改了一处忘了另一处就会悄悄漏给专家。这部分属于 AGENTS.md 的**账本级**(答案隔离)。
### tic.json
`src/cadx/build/_ceus.py` 的 `tic_view` 白名单改为只出下面两项,此外什么都不写:
```
{
"perfusion_metrics": {
"roi_pan": { 11 个指标 } 或 null,
"roi_perf": { 11 个指标 } 或 null
},
"keyframe_times_s": { "B0": 视频时间或 null, …, "F2": … }
}
```
- 11 个指标的键沿用 `summary.json` 里 `values` 下的键名(`PE_au`、`TTP_s` …),单项算不出为 null。`signal_domain`、`time_origin`、`area_curve`、`supporting_times_s` 都不要。
- `keyframe_times_s` 是 7 个槽位定位到的视频时间(秒),没取到为 null;未取到的原因不写。
- 去掉:`fits`(成败和 R²,四条曲线全部)、`pan_curve_usable`、`keyframes.*.located` 和 `reason`。原来对 `reason` 做的「不含视频号、路径」检查随字段一起删掉。
- 没装 CEUS 时照旧没有 tic.json。
### 8 张图放一个文件夹
医生截的关键图从 `ultrasound/key.png` 挪进 `ultrasound/keyframes/key.png`,和 `B0.png` … `F2.png` 放在一起;`ultrasound/` 下不再有单独的 `key.png`。
- 关键图来自交付包而不是 CEUS,所以没装 CEUS 的构建里 `keyframes/` 只有 `key.png` 一张,照样有这个文件夹。
- C14(保真重编码)对关键图和关键帧的规则不变。
- library 的读取接口相应改:`UltrasoundRoute` 不再有单独的关键图字段,`keyframes` 里多一个 `key`。其余使用者(review 等)跟着改。
### 测试(账本级)
预期值手写,不从实现里推:
- 用假交付包和假 CEUS 运行构建一次,逐例断言 `tic.json` 的**完整内容**等于手写的字典(不是只查几个键):两组都有、只有一组、两组都 null、某个单项为 null、某个槽位没取到各至少一例。
- 断言 tic.json 里不出现 `fits`、`r2`、`success`、`roi_all`、`background_circle`、`reason`、`pan_curve_usable` 这些键。
- 断言每例 `ultrasound/` 下的文件清单恰好是 `report.txt`、`tic.json`(装了 CEUS 时)、`keyframes/` 下的 `key.png` 加定位到的槽位;`key.png` 与原关键图逐像素相同。
- 没装 CEUS 的构建:`keyframes/` 下只有 `key.png`,没有 tic.json。
## 三、核对包
```
医生核对包_<构建号>/
说明.pdf
问题清单.csv
病例总表.csv
标准答案/ 4 张表照旧
病例/<病例号>/
临床信息.csv
超声报告.pdf
MR报告.pdf
关键帧/
医生截图.png 资料库 keyframes/key.png
<槽位>_第<秒>秒.png 秒数取 tic.json 的 keyframe_times_s
TIC曲线.png
TIC参数.csv 新增,取代 TIC结果.csv
回放视频.mp4
```
`TIC结果.csv` 和单独的 `关键图.png` 删掉。其余文件的拷贝规则、CSV 格式(BOM、中文列名、缺失为空)照任务书 03。
### TIC参数.csv
数值从**资料库的 tic.json** 读,不从 CEUS 运行读:医生核对的就是 agent 看到的那份。一例一张,行是 11 个指标,列:
| 列 | 内容 |
| --- | --- |
| 指标 | 中文名加缩写,如「达峰时间 TTP」 |
| 单位 | 秒、灰度、灰度·秒、灰度/秒 |
| 胰腺实质(紫圈) | 数值 |
| 病灶(去暗区) | 数值 |
- 时间类保留 1 位小数,其余保留 2 位。
- 某一组整组没算出时,该列全空,并在表的最后加一行:「指标」列写「没算出的原因」,对应列写一句医生能懂的话(见下文「原因的写法」)。两组都算出时没有这一行。原因从 CEUS 运行的 `summary.json` 读(资料库里已经没有了),这一行只给医生看,agent 拿到的只是 null;说明.pdf 不必提这个差别。
- 单项因观测不够算不出、而同组其他项有值时,该格留空,不另写原因(说明.pdf 里统一交代一次)。
- CEUS 失败的病例本来就不进资料库,没有这个文件。
### 问题清单.csv
列不变(病例号、视频号、环节、问题),内容改成每条一句大白话:
- 「问题」里不出现:检查编号(C10、C15 …)、英文原因码、JSON、文件路径、运行号、`roi_*` 之类的字段名、程序内部用词(band、谷值、互相关、模板匹配 …)。
- 「环节」改成医生认得的说法,例如「资料核对」「造影视频处理」「TIC 曲线」「关键帧」「紫圈」。
- 由同一个原因引起的多条合并成一条。例如病灶曲线拟合没成功导致 B0、D1–D4 都没取到,只写一条:「病灶曲线没能拟合,B0、D1–D4 这 5 个关键帧没有取」;不要再各写 5 行。
- 跨表不一致写出对不上的具体值,例如「三张表的年龄对不上:临床表 28 岁,超声表和 MR 表 63 岁」(这是病例数据,只进包,不进仓库、日志和报告)。
- 一个 CEUS 失败的病例只写一条(现在是「CEUS 第 N 步」和「装配资料库 C15」各一条,说的是同一件事)。
### 原因的写法
在 review 里维护一张「程序原因 → 医生能懂的一句话」的对照表,覆盖:跳过清单的每个检查编号、`failed.csv` 里各步的失败原因、拟合的每个原因码、关键帧每类未取到的原因、紫圈不可用。
- 对照表按「原因的种类」写,具体数值从原记录里取出来填进句子;数值对医生没意义的(谷值、像素偏移)不填。
- 遇到对照表里没有的原因**直接报错停下**,不能把程序原文漏给医生。
- 程序原文照旧留在 `snapshot/` 里(新增一份 `问题清单_原文.csv`,列同旧版),给我们自己追溯用,不进医生的目录。
写法参考(执行者可改得更顺,意思不变):
| 程序原因 | 给医生的话 |
| --- | --- |
| 第 1 步找不到分屏暗缝 | 视频里找不到左右两屏的分界线 |
| 第 1 步两半配准相差超过门槛 | 视频左右两屏的位置对不齐 |
| 第 2 步两半都没有绿框 | 视频里找不到画好的绿框 |
| 拟合 `parameter_on_boundary` | 曲线形状超出了程序预设的范围,没能拟合 |
| 拟合其他原因码 | 各写一句,说的是曲线本身的样子(太平、没有明显的峰、开头就已经很亮 …),不说算法 |
| 紫圈不可用 | 视频里大部分时间认不出紫圈 |
### 说明.pdf
整份重写,模板仍在 `src/cadx/review/` 下。
- **口吻**:合作者之间说话。用「我们」「你们」,不用「贵方」「请您核对」这类公文腔。开头一两句说清这是什么、想请他们帮忙看什么就行。
- **读者**:胰腺外科或超声科医生,懂 CEUS、懂 TIC 的临床意义,不懂编程、不懂我们的程序。
- **篇幅**:尽量 3 页内,最多 4 页。
- **只讲这些**:
1. 包里有什么、每个文件夹打开能看到什么(分条,不用长表);
2. 看病例的建议顺序:报告 → 关键帧文件夹里的医生截图 → 回放视频(黄色、绿色线是程序画的病灶轮廓,蓝色是程序认为一直不进造影剂的部分)→ TIC 曲线图 → 关键帧 → TIC 参数;
3. 7 个关键帧各是什么时刻,用临床的话说;
4. TIC 曲线图上每条线是什么(图上的英文标注逐个对照成中文);
5. 11 个指标各是什么意思,一句一个;两组的意思是让病灶和正常胰腺对着看;数值是在视频显示的灰度上算的,不是机器内部的回声强度,所以单看一个数意义不大,看两组的对比;时间从视频第一帧算起;空着表示没算出,最后一行写了原因;
6. 问题清单、病例总表、标准答案 4 张表各是什么,一句一个;
7. 包里有患者资料,只在我们双方之间传。
- **不写**:检查编号、原因码列表、字段名、算法和模型名(MedSAM2、Lognormal 等,Lognormal 可以说成「用一条平滑曲线去贴合」)、质量门的具体条件、构建配置开关、化名的设计理由。构建号、CEUS 运行号、生成日期放在第一页末尾一行小字即可。
- **排版**:现在的 PDF 有 4 张表(第 3、5 页的问题清单列说明、「环节」、「槽位」、「原因码」)在转换后只剩第一列。改完必须确认没有这种问题;能用分条就不用表。
## 四、验收要求(执行者自己做完再交)
1. **把 PDF 渲染成图片逐页看一遍**(`pdftoppm`),说明.pdf 全部页和一份超声报告 PDF。报告里写看过了、有没有发现问题。
2. **医生视角阅读**:派一个全新上下文的子 Agent,扮演「三甲医院胰腺外科医生,懂 CEUS,不会编程,第一次拿到这个包」,只给它:说明.pdf 转出的文字、`问题清单.csv`、一例病例目录里的 `TIC参数.csv` 和 `临床信息.csv`(用假交付包测试产出的那份,不给真实病例数据)。让它先复述「这个包让我看什么、怎么看」,再列出读不懂的句子、看不懂的词、觉得多余的内容、语气别扭的地方。这一轮替代 AGENTS.md 的「硕士生阅读」(读者不同)。格式建议不采纳,读不懂和多余的必须改。
3. 问题清单全文 `/usr/bin/grep` 一遍,确认不含:`C[0-9]`、`roi_`、`_`、`{`、`[`、`band`、运行号格式。写成测试。
## 测试
预期值照本任务书写,不从实现里推:
- 资料库:见第二部分「测试(账本级)」。
- 紫圈指标:假 CEUS 运行里造一例紫圈拟合成功的,`summary.json` 的 `perfusion_metrics` 恰好有 `roi_perf`、`roi_pan` 两个键,`roi_pan` 且 11 项值等于直接调 `compute_lognormal_perfusion_metrics` 的结果;`lesion_fit_ready` 的判定不受影响(造一例紫圈过、病灶有一条没过,D1–D4 仍不定位)。
- `TIC参数.csv`:列名、11 行的顺序和中文名;两组都有值、只有一组有值、两组都没有三种情况;「没算出的原因」行只在有组为空时出现;数值的小数位。
- 问题清单:每种原因至少一例,断言「环节」「问题」原文;拟合失败连带的关键帧只出一行;CEUS 失败只出一行;对照表里没有的原因报错;上面第 3 条的禁用字符检查。
- `snapshot/问题清单_原文.csv` 存在且内容与旧写法一致。
- 包里不再有 `TIC结果.csv` 和单独的 `关键图.png`;`关键帧/医生截图.png` 与资料库 `keyframes/key.png` 逐字节相同;`TIC参数.csv` 的数值与资料库 tic.json 逐项相同。
- build、ceus、review 原有测试照过(按本任务改了预期的除外,在报告里列出改了哪几条、为什么)。
## 文档
- `research-wiki/explanation/` 里讲 CEUS 第 9 步的地方:指标改为对病灶去暗区和紫圈两组算,写明来源是负责人 2026-10-17 的决定(医生要正常区与病灶对比看)。
- `research-wiki/guides/医生核对包.md`:文件清单改成新的;重跑顺序写成「干净工作区 → ceus_quant → build → review_pack」。
- `结构.md`:第四部分资料库布局(`key.png` 挪进 `keyframes/`)和 tic.json 字段说明重写(现在第 163–171 行一带);第八部分 `UltrasoundRoute` 的说明;规模表若有变化同步。
- `WORK_LOG.md`。
## 审阅
**资料库那部分是账本级**:先单独派一个全新上下文的子 Agent,只给本任务书第二部分、`结构.md` 第四部分(改后)和 build、library 的 diff,问一件事:专家现在能读到的超声一路,是否恰好是第二部分列的那些,多一个字段、多一个文件都算问题。处理完再做下面这轮。
核对包和 CEUS 属于「其余部分」那一档。写完派一个全新上下文的子 Agent,只给本任务书、diff 和渲染后的说明.pdf 页面图片。重点:问题清单里有没有漏出程序原文;对照表是否覆盖了真跑时出现的全部原因;紫圈指标改动有没有影响 D1–D4 的定位规则;review 有没有写 `library/` 或 `answers/`。Codex 连不上就跳过。
## 报告
1. 提交号;各部分行数变化。
2. `make check` 完整输出。
3. 新旧 CEUS 运行的对比(见「重跑」第 4 条);新的 CEUS、build、review_pack 三个运行号。
4. 紫圈、病灶去暗区两组各有几例算出了指标,两组都有的几例(只报计数);资料库任挑一例 tic.json 的键结构(只报键,不报数值)。
5. 问题清单按新「环节」分的行数,与旧版行数对比。
6. 渲染检查和医生视角阅读的结果,以及据此改了什么;两轮审阅的意见和处理。
7. 说明.pdf 和一例病例目录的路径,供负责人目视检查。
8. 和本任务书、`AGENTS.md` 不一致的地方,以及为什么。