longitudinal/scripts/01_build_ntuh_manifest.py
Furen Xiao b6fa62a763 feat: initial project structure
Add .gitignore, AGENTS.md, scripts directory, and src directory to initialize the repository.
2026-09-25 16:00:37 +08:00

54 lines
No EOL
1.8 KiB
Python

"""Build NTUH2022G4 labeled manifest: native T1c + tumor seg pairs from register_inv.
Fast listing-only pass (no volume decoding); content validated during preprocessing.
"""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import re
import json
from src.common import ROOT, save_jsonl
T1C_RE = re.compile(r"T1.*\+C")
EXCL_RE = re.compile(r"MRA|FLAIR|TOF|T2|SWI|DWI", re.I)
def main(limit=None):
out = os.path.join(ROOT, "data", "manifests", "ntuh.jsonl")
reg_inv = "/mnt/pve/SRS/NTUH2022G4/register_inv"
rows = []
n_subj = 0
for s in sorted(os.listdir(reg_inv)):
fp = os.path.join(reg_inv, s)
if not os.path.isdir(fp):
continue
n_subj += 1
for c in os.listdir(fp):
cp = os.path.join(fp, c)
if not os.path.isdir(cp):
continue
fl = set(os.listdir(cp))
for f in sorted(fl):
if not f.endswith(".nii.gz") or f.endswith((".seg.nii.gz", ".label.nii.gz")):
continue
if not T1C_RE.search(f) or EXCL_RE.search(f):
continue
seg = f[: -len(".nii.gz")] + ".seg.nii.gz"
if seg not in fl:
continue
rows.append({"key": f"ntuh_{s}_{c}", "subject": s, "case": c,
"date": c2date(c), "img": os.path.join(cp, f),
"label": os.path.join(cp, seg), "source": "ntuh"})
if limit and n_subj >= limit:
break
save_jsonl(rows, out)
print(f"subjects={n_subj} rows={len(rows)}")
def c2date(c):
m = re.match(r"case?(\d{4})\.(\d{2})\.(\d{2})\.", c)
return f"{m.group(1)}-{m.group(2)}-{m.group(3)}" if m else c
if __name__ == "__main__":
main()