ct_eval.py — CLI usage

End-to-end eval of TotalSegmentator body region + IV contrast against labeled CT series. Each series is analyzed for DICOM acquisition geometry before TotalSegmentator runs; localizers and other ineligible stacks are skipped with geometry recorded in the CSV.

Setup

uv sync --extra tseg

Requires TotalSegmentator and XGBoost. Does not use FALCON.

Run

uv run python src/prototyping/ct_eval.py [options]
Flag Default Description
--data-dir PATH ~/Downloads/A_DATA Root of labeled CT data
--output-dir PATH artifacts/ct_eval Directory for CSV and JSON summary
--per-class N all series Max series per label folder (e.g. HEAD_WITH, CHEST_WITHOUT)
-v / --verbose off DEBUG logging

Example (smoke test, 10 per label class):

uv run python src/prototyping/ct_eval.py \
  --data-dir /Users/michaelevans/Downloads/A_DATA \
  --output-dir artifacts/ct_eval_smoke \
  --per-class 10

Input layout (--data-dir)

Ground truth comes from first-level label directory names:

A_DATA/
  HEAD_WITH/<study_uid>/<series_uid>/*.dcm
  HEAD_WITHOUT/...
  CHEST_WITH/...
  CHEST_WITHOUT/...

Body part: Head, Chest, or Abdomen. Contrast: WITH or WITHOUT (also WO, NC, etc.).

Output files

ct_eval_results.csv — one row per series. Geometry columns (cached under <series>/.tseg_cache/geometry.json):

Column Example Meaning
geometry_planeaxialAcquisition plane
geometry_plane_confidence0.9512Plane classification confidence
geometry_dimensionalityvolume_3dvolume_3d, localizer_2d, single_slice_2d, …
geometry_provenanceoriginaloriginal / derived_3d_render / …
geometry_n_slices24Slice count in stack
geometry_ts_suitableTrueWhether TotalSegmentator should run
geometry_metadata_suspectFalseInconsistent DICOM headers flag
geometry_methoddicom_headersHow geometry was inferred

ct_eval_summary.json — aggregate accuracy plus geometry breakdowns:

Console report

Stdout includes a Geometry routing impact section (fail = TS skip or pipeline error), confusion matrices, and a per-series table with an acquisition plane column.