Download debug_dataloader.py from zhui711/omnigen_seg: direct link, hf CLI and curl.
- Browser
- Download file 3.52 kB
-
https://huggingface.co/zhui711/omnigen_seg/resolve/main/debug_dataloader.py
- Command line
-
hf download hf://zhui711/omnigen_seg/debug_dataloader.py
-
curl -L -o debug_dataloader.py https://huggingface.co/zhui711/omnigen_seg/resolve/main/debug_dataloader.py
3.52 kB
| #!/usr/bin/env python3 | |
| """ | |
| Debug script to inspect CXRSegDataset output. | |
| Checks whether the Heart channel (idx 2, class_id 51) is all-zeros. | |
| """ | |
| import sys | |
| import os | |
| import argparse | |
| # Make the vendored smp package importable | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), | |
| "segmentation_models_pytorch")) | |
| from segmentation_models_pytorch.datasets.cxr_seg_dataset import CXRSegDataset | |
| def main(): | |
| parser = argparse.ArgumentParser( | |
| description="Inspect CXRSegDataset mask channels for empty Heart/Aorta masks") | |
| parser.add_argument("--data_dir", type=str, required=True, | |
| help="Path to lidc_TotalSeg directory") | |
| parser.add_argument("--num_samples", type=int, default=50, | |
| help="Number of samples to inspect (default: 50)") | |
| args = parser.parse_args() | |
| # Channel name lookup (matches TARGET_GROUPS insertion order) | |
| channel_names = list(CXRSegDataset.TARGET_GROUPS.keys()) | |
| HEART_CH = 2 # "Heart" | |
| AORTA_CH = 3 # "Aorta" | |
| print(f"Channel mapping: {dict(enumerate(channel_names))}") | |
| print(f"Heart -> channel {HEART_CH} (class IDs {CXRSegDataset.TARGET_GROUPS['Heart']})") | |
| print(f"Aorta -> channel {AORTA_CH} (class IDs {CXRSegDataset.TARGET_GROUPS['Aorta']})") | |
| print() | |
| # Instantiate dataset without albumentations — uses fallback tensor conversion | |
| dataset = CXRSegDataset(root_dir=args.data_dir, transform=None) | |
| total = len(dataset) | |
| print(f"Dataset contains {total} samples total.") | |
| n = min(args.num_samples, total) | |
| if n == 0: | |
| print("No samples found. Exiting.") | |
| return | |
| print(f"Inspecting the first {n} samples ...\n") | |
| empty_heart = 0 | |
| empty_aorta = 0 | |
| for idx in range(n): | |
| batch = dataset[idx] | |
| mask = batch["mask"] # shape: (10, 256, 256) | |
| sums = [mask[ch].sum().item() for ch in range(mask.shape[0])] | |
| heart_sum = sums[HEART_CH] | |
| aorta_sum = sums[AORTA_CH] | |
| if heart_sum == 0: | |
| empty_heart += 1 | |
| if aorta_sum == 0: | |
| empty_aorta += 1 | |
| # Per-sample details for the first 10 and any with empty Heart | |
| if idx < 10 or heart_sum == 0: | |
| tag = " *** EMPTY Heart ***" if heart_sum == 0 else "" | |
| sample_info = batch.get("_debug_path", dataset.samples[idx]["mask_path"]) | |
| print(f"[{idx:3d}] {os.path.basename(sample_info)}{tag}") | |
| for ch, name in enumerate(channel_names): | |
| print(f" ch{ch} {name:16s}: sum={sums[ch]:10.1f}") | |
| print() | |
| # ---- Summary ---- | |
| print("=" * 60) | |
| print(f"SUMMARY (first {n} samples)") | |
| print(f" Empty Heart masks : {empty_heart} / {n}") | |
| print(f" Empty Aorta masks : {empty_aorta} / {n}") | |
| print() | |
| if empty_heart == n: | |
| print("!! ALL Heart masks are empty — likely a data-loading bug.") | |
| print(" Check: is class_id 51 present in labels_found for these patients?") | |
| # Quick diagnosis: check labels_found for first sample | |
| lf = dataset.samples[0]["labels_found"] | |
| print(f" Sample 0 labels_found includes 51? -> {51 in lf}") | |
| print(f" Sample 0 labels_found (first 20): {sorted(lf)[:20]}") | |
| elif empty_heart > 0: | |
| print(f"!! {empty_heart} samples have empty Heart masks (partial issue).") | |
| else: | |
| print("All samples have non-empty Heart masks. Channel 2 looks fine.") | |
| print("=" * 60) | |
| if __name__ == "__main__": | |
| main() | |