radmatch 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- radmatch/__init__.py +29 -0
- radmatch/assets/fewshot/README.md +37 -0
- radmatch/assets/fewshot/abdomen-ct/attribute_errors/README.md +26 -0
- radmatch/assets/fewshot/abdomen-ct/attribute_errors/example_1.json +38 -0
- radmatch/assets/fewshot/abdomen-ct/attribute_errors/example_2.json +28 -0
- radmatch/assets/fewshot/abdomen-ct/attribute_errors/example_3.json +35 -0
- radmatch/assets/fewshot/abdomen-ct/findings_gt/example_1.json +256 -0
- radmatch/assets/fewshot/abdomen-ct/findings_gt/example_2.json +247 -0
- radmatch/assets/fewshot/abdomen-ct/findings_gt/example_3.json +202 -0
- radmatch/assets/fewshot/abdomen-ct/findings_pred/example_1.json +254 -0
- radmatch/assets/fewshot/abdomen-ct/findings_pred/example_2.json +253 -0
- radmatch/assets/fewshot/abdomen-ct/findings_pred/example_3.json +196 -0
- radmatch/assets/fewshot/abdomen-ct/matching/README.md +30 -0
- radmatch/assets/fewshot/abdomen-ct/matching/example_1.json +150 -0
- radmatch/assets/fewshot/abdomen-ct/matching/example_2.json +97 -0
- radmatch/assets/fewshot/abdomen-ct/matching/example_3.json +84 -0
- radmatch/assets/fewshot/abdomen-ct/matching/example_4.json +53 -0
- radmatch/assets/fewshot/abdomen-ct/matching/example_5.json +47 -0
- radmatch/assets/fewshot/abdomen-ct/reports_gt/example_1.txt +2 -0
- radmatch/assets/fewshot/abdomen-ct/reports_gt/example_2.txt +5 -0
- radmatch/assets/fewshot/abdomen-ct/reports_gt/example_3.txt +2 -0
- radmatch/assets/fewshot/abdomen-ct/reports_pred/example_1.txt +2 -0
- radmatch/assets/fewshot/abdomen-ct/reports_pred/example_2.txt +5 -0
- radmatch/assets/fewshot/abdomen-ct/reports_pred/example_3.txt +3 -0
- radmatch/assets/fewshot/brain-mr/attribute_errors/README.md +11 -0
- radmatch/assets/fewshot/brain-mr/attribute_errors/example_1.json +23 -0
- radmatch/assets/fewshot/brain-mr/attribute_errors/example_2.json +35 -0
- radmatch/assets/fewshot/brain-mr/attribute_errors/example_3.json +30 -0
- radmatch/assets/fewshot/brain-mr/findings_gt/example_1.json +114 -0
- radmatch/assets/fewshot/brain-mr/findings_gt/example_2.json +160 -0
- radmatch/assets/fewshot/brain-mr/findings_gt/example_3.json +131 -0
- radmatch/assets/fewshot/brain-mr/findings_pred/example_1.json +93 -0
- radmatch/assets/fewshot/brain-mr/findings_pred/example_2.json +140 -0
- radmatch/assets/fewshot/brain-mr/findings_pred/example_3.json +131 -0
- radmatch/assets/fewshot/brain-mr/matching/README.md +28 -0
- radmatch/assets/fewshot/brain-mr/matching/example_1.json +99 -0
- radmatch/assets/fewshot/brain-mr/matching/example_2.json +97 -0
- radmatch/assets/fewshot/brain-mr/matching/example_3.json +66 -0
- radmatch/assets/fewshot/brain-mr/reports_gt/example_1.txt +34 -0
- radmatch/assets/fewshot/brain-mr/reports_gt/example_2.txt +23 -0
- radmatch/assets/fewshot/brain-mr/reports_gt/example_3.txt +30 -0
- radmatch/assets/fewshot/brain-mr/reports_pred/example_1.txt +37 -0
- radmatch/assets/fewshot/brain-mr/reports_pred/example_2.txt +22 -0
- radmatch/assets/fewshot/brain-mr/reports_pred/example_3.txt +27 -0
- radmatch/assets/fewshot/chest-ct/attribute_errors/README.md +11 -0
- radmatch/assets/fewshot/chest-ct/attribute_errors/example_1.json +37 -0
- radmatch/assets/fewshot/chest-ct/attribute_errors/example_2.json +23 -0
- radmatch/assets/fewshot/chest-ct/attribute_errors/example_3.json +23 -0
- radmatch/assets/fewshot/chest-ct/findings_gt/example_1.json +182 -0
- radmatch/assets/fewshot/chest-ct/findings_gt/example_2.json +346 -0
- radmatch/assets/fewshot/chest-ct/findings_gt/example_3.json +173 -0
- radmatch/assets/fewshot/chest-ct/findings_pred/example_1.json +182 -0
- radmatch/assets/fewshot/chest-ct/findings_pred/example_2.json +289 -0
- radmatch/assets/fewshot/chest-ct/findings_pred/example_3.json +173 -0
- radmatch/assets/fewshot/chest-ct/matching/README.md +28 -0
- radmatch/assets/fewshot/chest-ct/matching/example_1.json +123 -0
- radmatch/assets/fewshot/chest-ct/matching/example_2.json +90 -0
- radmatch/assets/fewshot/chest-ct/matching/example_3.json +84 -0
- radmatch/assets/fewshot/chest-ct/reports_gt/example_1.txt +52 -0
- radmatch/assets/fewshot/chest-ct/reports_gt/example_2.txt +96 -0
- radmatch/assets/fewshot/chest-ct/reports_gt/example_3.txt +59 -0
- radmatch/assets/fewshot/chest-ct/reports_pred/example_1.txt +52 -0
- radmatch/assets/fewshot/chest-ct/reports_pred/example_2.txt +78 -0
- radmatch/assets/fewshot/chest-ct/reports_pred/example_3.txt +59 -0
- radmatch/assets/fewshot/chest-xr/attribute_errors/README.md +11 -0
- radmatch/assets/fewshot/chest-xr/attribute_errors/example_1.json +35 -0
- radmatch/assets/fewshot/chest-xr/attribute_errors/example_2.json +37 -0
- radmatch/assets/fewshot/chest-xr/attribute_errors/example_3.json +33 -0
- radmatch/assets/fewshot/chest-xr/findings_gt/example_1.json +65 -0
- radmatch/assets/fewshot/chest-xr/findings_gt/example_2.json +65 -0
- radmatch/assets/fewshot/chest-xr/findings_gt/example_3.json +78 -0
- radmatch/assets/fewshot/chest-xr/findings_pred/example_1.json +58 -0
- radmatch/assets/fewshot/chest-xr/findings_pred/example_2.json +58 -0
- radmatch/assets/fewshot/chest-xr/findings_pred/example_3.json +57 -0
- radmatch/assets/fewshot/chest-xr/matching/README.md +28 -0
- radmatch/assets/fewshot/chest-xr/matching/example_1.json +32 -0
- radmatch/assets/fewshot/chest-xr/matching/example_2.json +85 -0
- radmatch/assets/fewshot/chest-xr/matching/example_3.json +66 -0
- radmatch/assets/fewshot/chest-xr/reports_gt/example_1.txt +24 -0
- radmatch/assets/fewshot/chest-xr/reports_gt/example_2.txt +19 -0
- radmatch/assets/fewshot/chest-xr/reports_gt/example_3.txt +21 -0
- radmatch/assets/fewshot/chest-xr/reports_pred/example_1.txt +21 -0
- radmatch/assets/fewshot/chest-xr/reports_pred/example_2.txt +17 -0
- radmatch/assets/fewshot/chest-xr/reports_pred/example_3.txt +17 -0
- radmatch/assets/fewshot/head-ct/attribute_errors/README.md +11 -0
- radmatch/assets/fewshot/head-ct/attribute_errors/example_1.json +30 -0
- radmatch/assets/fewshot/head-ct/attribute_errors/example_2.json +35 -0
- radmatch/assets/fewshot/head-ct/attribute_errors/example_3.json +28 -0
- radmatch/assets/fewshot/head-ct/findings_gt/example_1.json +44 -0
- radmatch/assets/fewshot/head-ct/findings_gt/example_2.json +105 -0
- radmatch/assets/fewshot/head-ct/findings_gt/example_3.json +141 -0
- radmatch/assets/fewshot/head-ct/findings_pred/example_1.json +51 -0
- radmatch/assets/fewshot/head-ct/findings_pred/example_2.json +98 -0
- radmatch/assets/fewshot/head-ct/findings_pred/example_3.json +113 -0
- radmatch/assets/fewshot/head-ct/matching/README.md +28 -0
- radmatch/assets/fewshot/head-ct/matching/example_1.json +82 -0
- radmatch/assets/fewshot/head-ct/matching/example_2.json +102 -0
- radmatch/assets/fewshot/head-ct/matching/example_3.json +66 -0
- radmatch/assets/fewshot/head-ct/reports_gt/example_1.txt +44 -0
- radmatch/assets/fewshot/head-ct/reports_gt/example_2.txt +50 -0
- radmatch/assets/fewshot/head-ct/reports_gt/example_3.txt +52 -0
- radmatch/assets/fewshot/head-ct/reports_pred/example_1.txt +46 -0
- radmatch/assets/fewshot/head-ct/reports_pred/example_2.txt +48 -0
- radmatch/assets/fewshot/head-ct/reports_pred/example_3.txt +48 -0
- radmatch/assets/prompts/prompt_attribute_errors.md +108 -0
- radmatch/assets/prompts/prompt_finding_extraction.md +237 -0
- radmatch/assets/prompts/prompt_indication_extraction.md +11 -0
- radmatch/assets/prompts/prompt_matching.md +93 -0
- radmatch/cli.py +312 -0
- radmatch/constants.py +187 -0
- radmatch/dashboard/Home.py +80 -0
- radmatch/dashboard/__init__.py +1 -0
- radmatch/dashboard/build_dashboard_data.py +130 -0
- radmatch/dashboard/common/__init__.py +1 -0
- radmatch/dashboard/common/constants.py +45 -0
- radmatch/dashboard/common/match_details.py +369 -0
- radmatch/dashboard/common/shared.py +819 -0
- radmatch/dashboard/launch.py +37 -0
- radmatch/dashboard/pages/1-Results_Explorer.py +576 -0
- radmatch/dashboard/pages/2-Performance_Summary.py +278 -0
- radmatch/dashboard/pages/__init__.py +1 -0
- radmatch/finding_extraction/__init__.py +5 -0
- radmatch/finding_extraction/extract_utils.py +287 -0
- radmatch/finding_extraction/inference.py +407 -0
- radmatch/indication_extraction/__init__.py +12 -0
- radmatch/indication_extraction/inference.py +152 -0
- radmatch/io.py +201 -0
- radmatch/llm_utils/__init__.py +1 -0
- radmatch/llm_utils/llm_clients.py +534 -0
- radmatch/llm_utils/prompts.py +272 -0
- radmatch/matching/__init__.py +21 -0
- radmatch/matching/inference.py +380 -0
- radmatch/matching/utils.py +191 -0
- radmatch/pipeline_runner.py +186 -0
- radmatch/scoring/__init__.py +10 -0
- radmatch/scoring/comparators.py +408 -0
- radmatch/scoring/inference.py +234 -0
- radmatch/scoring/metrics.py +445 -0
- radmatch/scoring/pipeline.py +498 -0
- radmatch-0.2.1.dist-info/METADATA +400 -0
- radmatch-0.2.1.dist-info/RECORD +144 -0
- radmatch-0.2.1.dist-info/WHEEL +4 -0
- radmatch-0.2.1.dist-info/entry_points.txt +3 -0
- radmatch-0.2.1.dist-info/licenses/LICENSE +201 -0
radmatch/__init__.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""RadMatch — LLM-based evaluation framework for radiology report generation.
|
|
2
|
+
|
|
3
|
+
`run_all` chains the three stages over a directory of reports; the per-stage functions
|
|
4
|
+
run them individually, each caching to disk so a costly earlier stage is reused.
|
|
5
|
+
See README.md.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from radmatch.finding_extraction.inference import ExtractionStats, extract_findings
|
|
11
|
+
from radmatch.indication_extraction.inference import extract_indications
|
|
12
|
+
from radmatch.llm_utils.llm_clients import assert_credentials_for
|
|
13
|
+
from radmatch.matching.inference import MatchingContext, match_dataset, match_findings
|
|
14
|
+
from radmatch.pipeline_runner import run_all
|
|
15
|
+
from radmatch.scoring.pipeline import ScoringContext, score_dataset, score_pair
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"ExtractionStats",
|
|
19
|
+
"MatchingContext",
|
|
20
|
+
"ScoringContext",
|
|
21
|
+
"assert_credentials_for",
|
|
22
|
+
"extract_findings",
|
|
23
|
+
"extract_indications",
|
|
24
|
+
"match_dataset",
|
|
25
|
+
"match_findings",
|
|
26
|
+
"run_all",
|
|
27
|
+
"score_dataset",
|
|
28
|
+
"score_pair",
|
|
29
|
+
]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Few-shot bundles
|
|
2
|
+
|
|
3
|
+
Pass `--fewshot <bundle>` to any subcommand to adapt the LLM to a dataset's report
|
|
4
|
+
style. Five bundles ship with RadMatch:
|
|
5
|
+
|
|
6
|
+
| Bundle | Modality |
|
|
7
|
+
|---|---|
|
|
8
|
+
| `abdomen-ct` | Abdominal CT |
|
|
9
|
+
| `brain-mr` | Brain MR |
|
|
10
|
+
| `chest-ct` | Chest CT |
|
|
11
|
+
| `chest-xr` | Chest X-ray |
|
|
12
|
+
| `head-ct` | Head CT |
|
|
13
|
+
|
|
14
|
+
The report text in these bundles is de-identified: dates, names, and institutions are
|
|
15
|
+
replaced with `[DATE]`, `[NAME]`, `[HOSPITAL]` placeholders. Where the source de-identifier
|
|
16
|
+
mis-tagged a series/image number as a date, the tag is left in place (e.g. `S301- [DATE:440]`
|
|
17
|
+
is series 301, image 440) — those are intra-study coordinates, not identifiers.
|
|
18
|
+
|
|
19
|
+
## Adding a bundle
|
|
20
|
+
|
|
21
|
+
Create `<bundle-name>/` here with this layout. A missing or incomplete directory logs a
|
|
22
|
+
warning and falls back to zero-shot prompting rather than failing.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
<bundle-name>/
|
|
26
|
+
├── reports_gt/ # Ground-truth report text: example_1.txt, example_2.txt, ...
|
|
27
|
+
├── reports_pred/ # Predicted report text: example_1.txt, ...
|
|
28
|
+
├── findings_gt/ # Stage 1 output for each GT report: example_1.json, ...
|
|
29
|
+
├── findings_pred/ # Stage 1 output for each pred report: example_1.json, ...
|
|
30
|
+
├── matching/ # Stage 2 examples: pred↔GT alignment
|
|
31
|
+
└── attribute_errors/ # Stage 3b examples: per-pair attribute errors
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`reports_*` are context for a human reading the bundle; the prompts consume
|
|
35
|
+
`findings_*`, `matching/` and `attribute_errors/`. Bundles installed from the wheel live
|
|
36
|
+
under `radmatch/assets/fewshot/` in site-packages, so a bundle of your own is easiest to
|
|
37
|
+
add in a source checkout.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Attribute-errors few-shot examples (abdomen-ct)
|
|
2
|
+
|
|
3
|
+
Three Stage 3b examples, each derived from the matches of the corresponding `abdomen-ct/matching/example_N.json`. INC pairs (status conflicts) are excluded — Stage 3b never sees them in production.
|
|
4
|
+
|
|
5
|
+
| File | Drawn from | Highlights |
|
|
6
|
+
|------|------------|------------|
|
|
7
|
+
| `example_1.json` | matching/example_1 | No free-text attribute errors — comparison flip on mesenteric LN and ratio diff on portal vein are owned by Stage 3a deterministic |
|
|
8
|
+
| `example_2.json` | matching/example_2 | No free-text attribute errors on the consolidated hematoma + active-bleeding match |
|
|
9
|
+
| `example_3.json` | matching/example_3 | Minor certainty error on hepatic-cyst pair (gt 'cyst' definite vs pred 'small hypodense focus' hedged); CBD prior-measurement diff is Stage 3a |
|
|
10
|
+
|
|
11
|
+
## Format
|
|
12
|
+
|
|
13
|
+
Each file is one example:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"scenario": "...",
|
|
18
|
+
"description": "...",
|
|
19
|
+
"user": { "series_uuid": "...", "pairs": [{"pred_finding": {...}, "gt_finding": {...}}, ...] },
|
|
20
|
+
"assistant": { "errors_per_match": [[...], [...], ...] }
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`user` and `assistant` are stored as raw JSON objects (parsed dicts at load time). `radmatch.llm_utils.prompts.load_attribute_errors_fewshot` reads these files when `--fewshot abdomen-ct` is passed, and the Stage 3b message builder serialises each side at construction time.
|
|
25
|
+
|
|
26
|
+
INC pairs (clinical_status mismatches) are excluded upstream in `evaluate_attribute_errors_batched`, so all pairs in these examples have matching `clinical_status` on both sides.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scenario": "No free-text attribute errors — deterministic comparators own these differences",
|
|
3
|
+
"description": "Stage 3b call derived from the matches in abdomen-ct/matching/example_1.json. The mesenteric-LN comparison flip (stable vs worsening) and the portal-vein percentage spread (60% vs 50–60%) are both handled by Stage 3a deterministic comparators, so Stage 3b emits no free-text attribute errors. The renal-cysts descriptor pair ('subcentimeter' vs 'small') is treated as near-synonymous — no error.",
|
|
4
|
+
"user": {
|
|
5
|
+
"series_uuid": "abdomen-ct_example_1",
|
|
6
|
+
"pairs": [
|
|
7
|
+
{
|
|
8
|
+
"pred_finding": {"finding_id": "p_1", "text": "Hepatic veins are patent.", "clinical_status": "normal", "clinical_significance": "routine", "comparison": null, "measurements": []},
|
|
9
|
+
"gt_finding": {"finding_id": "gt_1", "text": "Hepatic veins patent.", "clinical_status": "normal", "clinical_significance": "routine", "comparison": null, "measurements": []}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"pred_finding": {"finding_id": "p_2", "text": "Multiple small hypodense lesions in both kidneys, likely representing cysts.", "clinical_status": "abnormal", "clinical_significance": "notable", "comparison": null, "measurements": []},
|
|
13
|
+
"gt_finding": {"finding_id": "gt_2", "text": "Multiple subcentimeter hypodense lesions in the bilateral kidneys, likely small cysts.", "clinical_status": "abnormal", "clinical_significance": "notable", "comparison": null, "measurements": []}
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"pred_finding": {"finding_id": "p_3", "text": "No hydronephrosis.", "clinical_status": "normal", "clinical_significance": "routine", "comparison": null, "measurements": []},
|
|
17
|
+
"gt_finding": {"finding_id": "gt_3", "text": "No hydronephrosis.", "clinical_status": "normal", "clinical_significance": "routine", "comparison": null, "measurements": []}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"pred_finding": {"finding_id": "p_4", "text": "Three mesenteric lymph nodes measuring up to 12 mm, worsening compared to prior CT.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": "worsening", "measurements": [{"value": 3, "unit": null, "category": "count"}, {"value": 12, "unit": "mm", "category": "size"}]},
|
|
21
|
+
"gt_finding": {"finding_id": "gt_4", "text": "Three mesenteric lymph nodes measuring up to 12 mm, unchanged compared to prior CT.", "clinical_status": "abnormal", "clinical_significance": "notable", "comparison": "stable", "measurements": [{"value": 3, "unit": null, "category": "count"}, {"value": 12, "unit": "mm", "category": "size"}]}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"pred_finding": {"finding_id": "p_5", "text": "Portal vein shows approximately 50-60% narrowing at the porta hepatis.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": null, "measurements": [{"value": 50, "unit": "pct", "category": "ratio"}, {"value": 60, "unit": "pct", "category": "ratio"}]},
|
|
25
|
+
"gt_finding": {"finding_id": "gt_5", "text": "Main portal vein demonstrates approximately 60% luminal narrowing at the porta hepatis.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": null, "measurements": [{"value": 60, "unit": "pct", "category": "ratio"}]}
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"assistant": {
|
|
30
|
+
"errors_per_match": [
|
|
31
|
+
[],
|
|
32
|
+
[],
|
|
33
|
+
[],
|
|
34
|
+
[],
|
|
35
|
+
[]
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scenario": "No free-text attribute errors on consolidated trauma findings",
|
|
3
|
+
"description": "Stage 3b call derived from the matches in abdomen-ct/matching/example_2.json. The adductor hematoma + active-bleeding entries are consolidated descriptions of the same lesion and align cleanly. The pred 'Findings-section text initially described the lesion as 9 x 6 cm' clause documents a pred report inconsistency rather than a Stage 3b-scoreable attribute error. None of the 4 LLM attribute dimensions (location, severity, morphology, certainty) apply to the matched pairs.",
|
|
4
|
+
"user": {
|
|
5
|
+
"series_uuid": "abdomen-ct_example_2",
|
|
6
|
+
"pairs": [
|
|
7
|
+
{
|
|
8
|
+
"pred_finding": {"finding_id": "p_1", "text": "Gallbladder surgically absent.", "clinical_status": "abnormal", "clinical_significance": "notable", "comparison": null, "measurements": []},
|
|
9
|
+
"gt_finding": {"finding_id": "gt_1", "text": "Gallbladder surgically absent.", "clinical_status": "abnormal", "clinical_significance": "notable", "comparison": null, "measurements": []}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"pred_finding": {"finding_id": "p_2", "text": "Left adductor intramuscular hematoma measuring 7 x 4.7 cm (decreased from 9 x 5 cm on prior exam) with a small 6 mm central focus of hyperdensity on early-phase imaging that did not persist on delayed imaging. Findings-section text initially described the lesion as 9 x 6 cm.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": "improving", "measurements": [{"value": 7, "unit": "cm", "category": "size"}, {"value": 4.7, "unit": "cm", "category": "size"}, {"value": 9, "unit": "cm", "category": "size"}, {"value": 5, "unit": "cm", "category": "size"}, {"value": 6, "unit": "mm", "category": "size"}]},
|
|
13
|
+
"gt_finding": {"finding_id": "gt_2", "text": "Left adductor intramuscular hematoma measuring 7 x 4.7 cm (decreased from 9 x 5 cm on prior exam) with a small 6 mm central focus of hyperdensity / contrast blush on early-phase imaging that did not persist on delayed imaging.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": "improving", "measurements": [{"value": 7, "unit": "cm", "category": "size"}, {"value": 4.7, "unit": "cm", "category": "size"}, {"value": 9, "unit": "cm", "category": "size"}, {"value": 5, "unit": "cm", "category": "size"}, {"value": 6, "unit": "mm", "category": "size"}]}
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"pred_finding": {"finding_id": "p_3", "text": "Small focus of slow, active bleeding which did not continue on delays, versus pseudoaneurysm.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": null, "measurements": []},
|
|
17
|
+
"gt_finding": {"finding_id": "gt_3", "text": "Small focus of slow, active bleeding which did not continue on delays, versus pseudoaneurysm.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": null, "measurements": []}
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"assistant": {
|
|
22
|
+
"errors_per_match": [
|
|
23
|
+
[],
|
|
24
|
+
[],
|
|
25
|
+
[]
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scenario": "Certainty minor + clean pairs (size/comparison handled deterministically)",
|
|
3
|
+
"description": "Stage 3b call derived from the matches in abdomen-ct/matching/example_3.json. The hepatic-cyst pair's size + comparison losses (gt 9 mm + stable; pred drops both) are deterministic Stage 3a concerns. There is also a certainty diff on the hepatic-cyst pair: gt asserts a definite 'cyst', pred hedges to 'small hypodense focus' — a one-step certainty difference (definite vs hedged-descriptive) without crossing into 'possible / cannot exclude', tagged minor. CBD prior-measurement difference (6 mm vs 5 mm) is Stage 3a.",
|
|
4
|
+
"user": {
|
|
5
|
+
"series_uuid": "abdomen-ct_example_3",
|
|
6
|
+
"pairs": [
|
|
7
|
+
{
|
|
8
|
+
"pred_finding": {"finding_id": "p_1", "text": "Small hypodense focus within the right hepatic lobe.", "clinical_status": "abnormal", "clinical_significance": "notable", "comparison": null, "measurements": []},
|
|
9
|
+
"gt_finding": {"finding_id": "gt_1", "text": "Cyst in the right hepatic lobe measuring 9 mm unchanged.", "clinical_status": "abnormal", "clinical_significance": "notable", "comparison": "stable", "measurements": [{"value": 9, "unit": "mm", "category": "size"}]}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"pred_finding": {"finding_id": "p_2", "text": "Common bile duct measures up to 8 mm, increased from 5 mm previously, and tapers distally.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": "worsening", "measurements": [{"value": 8, "unit": "mm", "category": "size"}, {"value": 5, "unit": "mm", "category": "size"}]},
|
|
13
|
+
"gt_finding": {"finding_id": "gt_2", "text": "Common bile duct measures up to 8 mm, increased from 6 mm previously, and tapers distally.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": "worsening", "measurements": [{"value": 8, "unit": "mm", "category": "size"}, {"value": 6, "unit": "mm", "category": "size"}]}
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"pred_finding": {"finding_id": "p_3", "text": "Focus of internal density within the common bile duct.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": null, "measurements": []},
|
|
17
|
+
"gt_finding": {"finding_id": "gt_3", "text": "Focus of internal density within the common bile duct.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": null, "measurements": []}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"pred_finding": {"finding_id": "p_4", "text": "2 cm structure with fecalized internal contents associated with the proximal jejunum, not identified on the prior study, causing approximately 50% luminal narrowing.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": "new", "measurements": [{"value": 2, "unit": "cm", "category": "size"}, {"value": 50, "unit": "pct", "category": "ratio"}]},
|
|
21
|
+
"gt_finding": {"finding_id": "gt_4", "text": "Approximately 2 cm structure with fecalized internal contents associated with the proximal jejunum, not identified on the prior study, causing approximately 50% luminal narrowing.", "clinical_status": "abnormal", "clinical_significance": "urgent", "comparison": "new", "measurements": [{"value": 2, "unit": "cm", "category": "size"}, {"value": 50, "unit": "pct", "category": "ratio"}]}
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"assistant": {
|
|
26
|
+
"errors_per_match": [
|
|
27
|
+
[
|
|
28
|
+
{"dimension": "certainty", "severity": "minor", "reasoning": "Gt asserts a definite cyst; pred hedges to 'small hypodense focus' — one step down on the certainty scale without crossing into 'possible / cannot exclude'."}
|
|
29
|
+
],
|
|
30
|
+
[],
|
|
31
|
+
[],
|
|
32
|
+
[]
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"text": "Bibasilar dependent atelectasis.",
|
|
4
|
+
"measurements": [],
|
|
5
|
+
"comparison": null,
|
|
6
|
+
"clinical_status": "abnormal",
|
|
7
|
+
"clinical_significance": "notable"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"text": "Liver normal.",
|
|
11
|
+
"measurements": [],
|
|
12
|
+
"comparison": null,
|
|
13
|
+
"clinical_status": "normal",
|
|
14
|
+
"clinical_significance": "routine"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"text": "Biliary tree normal.",
|
|
18
|
+
"measurements": [],
|
|
19
|
+
"comparison": null,
|
|
20
|
+
"clinical_status": "normal",
|
|
21
|
+
"clinical_significance": "routine"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"text": "Hepatic veins patent.",
|
|
25
|
+
"measurements": [],
|
|
26
|
+
"comparison": null,
|
|
27
|
+
"clinical_status": "normal",
|
|
28
|
+
"clinical_significance": "routine"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"text": "Portal veins patent.",
|
|
32
|
+
"measurements": [],
|
|
33
|
+
"comparison": null,
|
|
34
|
+
"clinical_status": "normal",
|
|
35
|
+
"clinical_significance": "routine"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"text": "No intrahepatic biliary dilatation.",
|
|
39
|
+
"measurements": [],
|
|
40
|
+
"comparison": null,
|
|
41
|
+
"clinical_status": "normal",
|
|
42
|
+
"clinical_significance": "routine"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"text": "Gallbladder normal.",
|
|
46
|
+
"measurements": [],
|
|
47
|
+
"comparison": null,
|
|
48
|
+
"clinical_status": "normal",
|
|
49
|
+
"clinical_significance": "routine"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"text": "Common bile duct measures up to 7 mm in diameter, but tapers distally.",
|
|
53
|
+
"measurements": [
|
|
54
|
+
{
|
|
55
|
+
"value": 7,
|
|
56
|
+
"unit": "mm",
|
|
57
|
+
"category": "size"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"comparison": null,
|
|
61
|
+
"clinical_status": "normal",
|
|
62
|
+
"clinical_significance": "routine"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"text": "Spleen normal.",
|
|
66
|
+
"measurements": [],
|
|
67
|
+
"comparison": null,
|
|
68
|
+
"clinical_status": "normal",
|
|
69
|
+
"clinical_significance": "routine"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"text": "Pancreas normal.",
|
|
73
|
+
"measurements": [],
|
|
74
|
+
"comparison": null,
|
|
75
|
+
"clinical_status": "normal",
|
|
76
|
+
"clinical_significance": "routine"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"text": "Adrenal glands normal.",
|
|
80
|
+
"measurements": [],
|
|
81
|
+
"comparison": null,
|
|
82
|
+
"clinical_status": "normal",
|
|
83
|
+
"clinical_significance": "routine"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"text": "Multiple subcentimeter hypodense lesions in the bilateral kidneys, likely small cysts.",
|
|
87
|
+
"measurements": [],
|
|
88
|
+
"comparison": null,
|
|
89
|
+
"clinical_status": "abnormal",
|
|
90
|
+
"clinical_significance": "notable"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"text": "No hydronephrosis.",
|
|
94
|
+
"measurements": [],
|
|
95
|
+
"comparison": null,
|
|
96
|
+
"clinical_status": "normal",
|
|
97
|
+
"clinical_significance": "routine"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"text": "No obstructing renal calculi.",
|
|
101
|
+
"measurements": [],
|
|
102
|
+
"comparison": null,
|
|
103
|
+
"clinical_status": "normal",
|
|
104
|
+
"clinical_significance": "routine"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"text": "Gastrointestinal tract normal.",
|
|
108
|
+
"measurements": [],
|
|
109
|
+
"comparison": null,
|
|
110
|
+
"clinical_status": "normal",
|
|
111
|
+
"clinical_significance": "routine"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"text": "Appendix normal.",
|
|
115
|
+
"measurements": [],
|
|
116
|
+
"comparison": null,
|
|
117
|
+
"clinical_status": "normal",
|
|
118
|
+
"clinical_significance": "routine"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"text": "No significant diverticulosis.",
|
|
122
|
+
"measurements": [],
|
|
123
|
+
"comparison": null,
|
|
124
|
+
"clinical_status": "normal",
|
|
125
|
+
"clinical_significance": "routine"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"text": "No evidence of diverticulitis.",
|
|
129
|
+
"measurements": [],
|
|
130
|
+
"comparison": null,
|
|
131
|
+
"clinical_status": "normal",
|
|
132
|
+
"clinical_significance": "routine"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"text": "No evidence of obstruction.",
|
|
136
|
+
"measurements": [],
|
|
137
|
+
"comparison": null,
|
|
138
|
+
"clinical_status": "normal",
|
|
139
|
+
"clinical_significance": "routine"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"text": "No free fluid.",
|
|
143
|
+
"measurements": [],
|
|
144
|
+
"comparison": null,
|
|
145
|
+
"clinical_status": "normal",
|
|
146
|
+
"clinical_significance": "routine"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"text": "Bladder normal.",
|
|
150
|
+
"measurements": [],
|
|
151
|
+
"comparison": null,
|
|
152
|
+
"clinical_status": "normal",
|
|
153
|
+
"clinical_significance": "routine"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"text": "Uterus normal.",
|
|
157
|
+
"measurements": [],
|
|
158
|
+
"comparison": null,
|
|
159
|
+
"clinical_status": "normal",
|
|
160
|
+
"clinical_significance": "routine"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"text": "Ovaries normal.",
|
|
164
|
+
"measurements": [],
|
|
165
|
+
"comparison": null,
|
|
166
|
+
"clinical_status": "normal",
|
|
167
|
+
"clinical_significance": "routine"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"text": "Atherosclerosis present.",
|
|
171
|
+
"measurements": [],
|
|
172
|
+
"comparison": null,
|
|
173
|
+
"clinical_status": "abnormal",
|
|
174
|
+
"clinical_significance": "notable"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"text": "No aneurysm.",
|
|
178
|
+
"measurements": [],
|
|
179
|
+
"comparison": null,
|
|
180
|
+
"clinical_status": "normal",
|
|
181
|
+
"clinical_significance": "routine"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"text": "Prominent inguinal lymph nodes, but not enlarged by size criteria.",
|
|
185
|
+
"measurements": [],
|
|
186
|
+
"comparison": null,
|
|
187
|
+
"clinical_status": "abnormal",
|
|
188
|
+
"clinical_significance": "notable"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"text": "Prominent left paraaortic lymph nodes, but not enlarged by size criteria.",
|
|
192
|
+
"measurements": [],
|
|
193
|
+
"comparison": null,
|
|
194
|
+
"clinical_status": "abnormal",
|
|
195
|
+
"clinical_significance": "notable"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"text": "Three mesenteric lymph nodes measuring up to 12 mm, unchanged compared to prior CT.",
|
|
199
|
+
"measurements": [
|
|
200
|
+
{
|
|
201
|
+
"value": 3,
|
|
202
|
+
"unit": null,
|
|
203
|
+
"category": "count"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"value": 12,
|
|
207
|
+
"unit": "mm",
|
|
208
|
+
"category": "size"
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
"comparison": "stable",
|
|
212
|
+
"clinical_status": "abnormal",
|
|
213
|
+
"clinical_significance": "notable"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"text": "Abdominal wall normal.",
|
|
217
|
+
"measurements": [],
|
|
218
|
+
"comparison": null,
|
|
219
|
+
"clinical_status": "normal",
|
|
220
|
+
"clinical_significance": "routine"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"text": "Multilevel degenerative changes of the lower thoracic spine, unchanged compared to prior imaging.",
|
|
224
|
+
"measurements": [],
|
|
225
|
+
"comparison": "stable",
|
|
226
|
+
"clinical_status": "abnormal",
|
|
227
|
+
"clinical_significance": "notable"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"text": "Multilevel degenerative changes of the lumbar spine, unchanged compared to prior imaging.",
|
|
231
|
+
"measurements": [],
|
|
232
|
+
"comparison": "stable",
|
|
233
|
+
"clinical_status": "abnormal",
|
|
234
|
+
"clinical_significance": "notable"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"text": "Main portal vein demonstrates approximately 60% luminal narrowing at the porta hepatis.",
|
|
238
|
+
"measurements": [
|
|
239
|
+
{
|
|
240
|
+
"value": 60,
|
|
241
|
+
"unit": "pct",
|
|
242
|
+
"category": "ratio"
|
|
243
|
+
}
|
|
244
|
+
],
|
|
245
|
+
"comparison": null,
|
|
246
|
+
"clinical_status": "abnormal",
|
|
247
|
+
"clinical_significance": "urgent"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"text": "No evidence of obstruction, diverticulitis, appendicitis, nephrolithiasis, or other acute findings to explain the patient's clinical symptoms.",
|
|
251
|
+
"measurements": [],
|
|
252
|
+
"comparison": null,
|
|
253
|
+
"clinical_status": "normal",
|
|
254
|
+
"clinical_significance": "routine"
|
|
255
|
+
}
|
|
256
|
+
]
|