From 4eb4f6f2fc22a3620738d992824a222fe0e8c7ce Mon Sep 17 00:00:00 2001 From: "jiacheng.lin" Date: Fri, 17 Jul 2026 10:43:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20CompactTableShell?= =?UTF-8?q?=20=E7=BB=84=E4=BB=B6=E7=9A=84=E6=A0=B7=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E7=A1=AE=E4=BF=9D=E8=A1=A8=E6=A0=BC=E5=9C=A8=E5=B0=8F=E5=B1=8F?= =?UTF-8?q?=E5=B9=95=E4=B8=8A=E5=8F=AF=E6=BB=9A=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platform/as_platform/data/core.py | 88 ++++++++++++++++--- .../web/src/components/CompactTableShell.tsx | 4 +- 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/platform/as_platform/data/core.py b/platform/as_platform/data/core.py index ef670e9..b39dfca 100644 --- a/platform/as_platform/data/core.py +++ b/platform/as_platform/data/core.py @@ -967,11 +967,81 @@ def _build_catalog(wf: dict, *, prefer_reports: bool = True) -> tuple[dict[str, "quality": lane_quality, } + # ── ADAS label collection helpers ── + + def _collect_adas_label_stats(batch_dir: Path, class_name_map: dict[int, str]) -> dict[str, Any]: + """Scan all known ADAS label formats and return {label_count, class_counts}.""" + label_count = 0 + class_counts: dict[str, int] = {} + + # 1. quaternion_json — standard 2D/3D detection JSON + qdir = batch_dir / "labels" / "quaternion_json" + if qdir.is_dir(): + for qf in sorted(qdir.glob("*.json")): + try: + qdata = json.loads(qf.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + continue + for det in qdata.get("detections") or []: + label_count += 1 + cls = str(det.get("class_name") or det.get("class_id", "unknown")) + class_counts[cls] = class_counts.get(cls, 0) + 1 + + # 2. yolo-hbb — YOLO horizontal bounding box text files + yolo_dir = batch_dir / "labels" / "yolo-hbb" + if yolo_dir.is_dir(): + for txt in sorted(yolo_dir.glob("*.txt")): + try: + for line in txt.read_text(encoding="utf-8", errors="ignore").splitlines(): + line = line.strip() + if not line: + continue + parts = line.split() + try: + cls_id = int(float(parts[0])) + except (ValueError, IndexError): + continue + cls_name = class_name_map.get(cls_id, f"class_{cls_id}") + class_counts[cls_name] = class_counts.get(cls_name, 0) + 1 + label_count += 1 + except OSError: + continue + + return {"label_count": label_count, "class_counts": class_counts} + # ── ADAS catalog ── adas_root = proj_root(wf, "adas") out["adas"] = {} adas_packs_dir = adas_root / "packs" if adas_packs_dir.is_dir(): + # Pre-scan for quaternion_json text_prompts to build class name maps per task + _task_class_names: dict[str, dict[int, str]] = {} # task → {class_id: class_name} + for pack_dir in sorted(adas_packs_dir.iterdir()): + if pack_dir.name.startswith(".") or not pack_dir.is_dir(): + continue + sources_dir = pack_dir / "sources" + if not sources_dir.is_dir(): + continue + for batch_dir in sorted(sources_dir.iterdir()): + if batch_dir.name.startswith(".") or not batch_dir.is_dir(): + continue + qdir = batch_dir / "labels" / "quaternion_json" + if not qdir.is_dir(): + continue + meta = read_meta(batch_dir) or {} + task = meta.get("task", "") + if not task or task in _task_class_names: + continue + try: + first_qf = next(qdir.glob("*.json"), None) + if first_qf: + qdata = json.loads(first_qf.read_text(encoding="utf-8")) + prompts = qdata.get("text_prompts") + if isinstance(prompts, list) and prompts: + _task_class_names[task] = {i: str(name) for i, name in enumerate(prompts)} + except (OSError, json.JSONDecodeError, StopIteration): + continue + for pack_dir in sorted(adas_packs_dir.iterdir()): if pack_dir.name.startswith(".") or not pack_dir.is_dir(): continue @@ -996,20 +1066,14 @@ def _build_catalog(wf: dict, *, prefer_reports: bool = True) -> tuple[dict[str, task = meta.get("task", "") counts = meta.get("counts", {}) img_count = counts.get("images", 0) - # Count quaternion_json detections - qdir = batch_dir / "labels" / "quaternion_json" label_count = 0 class_counts: dict[str, int] = {} - if qdir.is_dir(): - for qf in sorted(qdir.glob("*.json")): - try: - qdata = json.loads(qf.read_text(encoding="utf-8")) - except (OSError, json.JSONDecodeError): - continue - for det in qdata.get("detections") or []: - label_count += 1 - cls = str(det.get("class_name") or det.get("class_id", "unknown")) - class_counts[cls] = class_counts.get(cls, 0) + 1 + + # Collect label stats from all known ADAS label formats + label_stats = _collect_adas_label_stats(batch_dir, _task_class_names.get(task, {})) + label_count = label_stats["label_count"] + class_counts = label_stats["class_counts"] + # Count images from directory if meta is missing if img_count == 0: imgs_dir = batch_dir / "images" diff --git a/platform/web/src/components/CompactTableShell.tsx b/platform/web/src/components/CompactTableShell.tsx index abd178c..6826204 100644 --- a/platform/web/src/components/CompactTableShell.tsx +++ b/platform/web/src/components/CompactTableShell.tsx @@ -8,8 +8,8 @@ type CompactTableShellProps = { }; export const CompactTableShell: React.FC = ({ children, colWidths }) => ( -
-
+
+
{colWidths && colWidths.length > 0 && (