Download code/ct/predict_report.py from odurugol/vlm3d-beyond-normals: direct link, hf CLI and curl.
- Browser
- Download file 2.18 kB
-
https://huggingface.co/odurugol/vlm3d-beyond-normals/resolve/main/code/ct/predict_report.py
- Command line
-
hf download hf://odurugol/vlm3d-beyond-normals/code/ct/predict_report.py
-
curl -L -o predict_report.py https://huggingface.co/odurugol/vlm3d-beyond-normals/resolve/main/code/ct/predict_report.py
2.18 kB
| """CT report generation: a folder of .nii.gz volumes -> challenge report JSON. | |
| python predict_report.py --weights ct_classification \ | |
| --writer ct_report_generation/report_writer.json \ | |
| --input scans/ --output reports.json | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import re | |
| from pathlib import Path | |
| import numpy as np | |
| import torch | |
| from fusion import FusionPolicy | |
| from predict_classification import case_name, load_models, predict_logits | |
| from report_writer import ReportWriter | |
| UUID = re.compile(r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", re.I) | |
| def report_name(path: Path) -> str: | |
| """The report track names a case by the trailing UUID in its file name, if there is one.""" | |
| stem = case_name(path) | |
| return next((part for part in reversed(stem.split("_")) if UUID.fullmatch(part)), stem) | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--weights", type=Path, required=True) | |
| ap.add_argument("--writer", type=Path, required=True) | |
| ap.add_argument("--input", type=Path, required=True) | |
| ap.add_argument("--output", type=Path, required=True) | |
| args = ap.parse_args() | |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| labels, models, cfgs = load_models(args.weights, device) | |
| policy = FusionPolicy(args.weights / "fusion_policy.json") | |
| writer = ReportWriter(args.writer) | |
| assert policy.labels == labels == writer.labels | |
| paths = sorted(args.input.rglob("*.nii.gz")) | |
| names = [report_name(p) for p in paths] | |
| assert len(set(names)) == len(names), "duplicate case names" | |
| logits = np.stack([predict_logits(p, models, cfgs, device) for p in paths]) | |
| _, emitted = policy(logits) | |
| reports = [{"input_image_name": n, "report": writer.render(row)} for n, row in zip(names, emitted)] | |
| out = [{"outputs": [{"value": {"name": "Generated reports", "type": "Report generation", | |
| "version": "1.0", "generated_reports": reports}}]}] | |
| args.output.parent.mkdir(parents=True, exist_ok=True) | |
| args.output.write_text(json.dumps(out, ensure_ascii=False)) | |
| if __name__ == "__main__": | |
| main() | |