"""Aggregated reporting: quality metrics, funnel, groups, haystack, benchmark. Ground-truth integrity (spec ยง41): precision/recall are only computed when a reference exists; model confidence is never presented as precision; recall is never inferred from anomaly scores. """ from __future__ import annotations import math from collections import defaultdict from typing import Dict, List, Optional import numpy as np from sensorflow.evaluation import synthetic from sensorflow.evaluation.process_units import usage_summary from sensorflow.evaluation.records import ( Benchmark, BenchmarkResult, EvalStore, SAFETY_CRITICAL_CLASSES, new_id, ) TP_IOU = 0.5 # ------------------------------------------------------------------ matching def _match_stats(store: EvalStore, dataset_id: str, frame_ids: Optional[set] = None, class_name: Optional[str] = None) -> Dict: """TP/FP/FN over annotations vs reference GT (only where reference exists).""" frames = store.where("frames", dataset_id=dataset_id) if frame_ids is not None: frames = [f for f in frames if f.frame_id in frame_ids] fid_set = {f.frame_id for f in frames} anns = [a for a in store.where("annotations", dataset_id=dataset_id) if a.frame_id in fid_set and a.status != "REJECTED"] if class_name: anns = [a for a in anns if a.class_name == class_name] gt_total = 0 gt_hit: Dict[str, bool] = {} for f in frames: for g in f.gt_boxes: if class_name and g.class_name != class_name: continue gt_total += 1 gt_hit[g.gt_id] = False tp = fp = 0 for a in anns: v = store.get("validations", a.annotation_id) iou = v.iou_3d if v else None if a.matched_gt_id and a.matched_gt_id in gt_hit and iou is not None and iou >= TP_IOU: if not gt_hit[a.matched_gt_id]: gt_hit[a.matched_gt_id] = True tp += 1 else: fp += 1 else: fp += 1 fn = sum(1 for hit in gt_hit.values() if not hit) return {"tp": tp, "fp": fp, "fn": fn, "gt_total": gt_total, "n_annotations": len(anns)} def _prf(stats: Dict) -> Dict[str, Optional[float]]: tp, fp, fn = stats["tp"], stats["fp"], stats["fn"] if stats["gt_total"] == 0 and tp + fp == 0: return {"precision": None, "recall": None, "f1": None} precision = tp / (tp + fp) if (tp + fp) > 0 else None recall = tp / (tp + fn) if (tp + fn) > 0 else None f1 = None if precision is not None and recall is not None and (precision + recall) > 0: f1 = 2 * precision * recall / (precision + recall) r = lambda v: round(v, 4) if v is not None else None return {"precision": r(precision), "recall": r(recall), "f1": r(f1)} # ------------------------------------------------------------------ metrics def quality_metrics(store: EvalStore, dataset_id: Optional[str]) -> Dict: dataset = store.get("datasets", dataset_id) if dataset_id else None empty = { "dataset_id": dataset_id, "gt_available": False, "gt_type": None, "gt_coverage": 0.0, "global": {k: None for k in ( "precision", "recall", "f1", "map_3d", "safety_critical_recall", "mean_iou_3d", "mean_position_error", "mean_orientation_error_deg", "idf1", "id_swap_rate", "fragmentation_rate", "grader_consensus")} | {"anomaly_rate": 0.0}, "per_class": [], "per_scenario": [], } if dataset is None: return empty anns = [a for a in store.where("annotations", dataset_id=dataset_id) if a.status != "REJECTED"] if not anns: return empty gt_available = dataset.gt_coverage > 0 stats = _match_stats(store, dataset_id) prf = _prf(stats) if gt_available else {"precision": None, "recall": None, "f1": None} # Safety-critical recall (reference required). saf_tp = saf_fn = 0 for cls in SAFETY_CRITICAL_CLASSES: s = _match_stats(store, dataset_id, class_name=cls) saf_tp += s["tp"] saf_fn += s["fn"] safety_recall = round(saf_tp / (saf_tp + saf_fn), 4) if gt_available and (saf_tp + saf_fn) > 0 else None # Geometry means over matched labels. ious, pos_errs, yaw_errs = [], [], [] anomaly_flags, consensus_vals = [], [] switches = frags = tracked = 0 for a in anns: v = store.get("validations", a.annotation_id) if v: if v.iou_3d is not None: ious.append(v.iou_3d) if v.position_error is not None: pos_errs.append(v.position_error) if v.orientation_error_deg is not None: yaw_errs.append(v.orientation_error_deg) an = store.get("anomalies", a.annotation_id) if an: anomaly_flags.append(1.0 if an.is_anomaly else 0.0) g = store.get("grader_comparisons", a.annotation_id) if g and g.consensus is not None: consensus_vals.append(g.consensus) t = store.get("tracking_evidence", a.annotation_id) if t and a.matched_gt_id: tracked += 1 switches += 1 if t.id_switch else 0 frags += 1 if t.fragmentation else 0 id_swap_rate = round(switches / tracked, 4) if tracked else None frag_rate = round(frags / tracked, 4) if tracked else None # IDF1 approximation from identity error rates (full IDF1 needs global # bipartite matching; this monotone surrogate is used consistently). idf1 = None if id_swap_rate is not None and frag_rate is not None: idf1 = round(max(0.0, 1.0 - id_swap_rate - 0.5 * frag_rate), 4) map_3d = _map_3d(store, dataset_id) if gt_available else None glob = { "precision": prf["precision"], "recall": prf["recall"], "f1": prf["f1"], "map_3d": map_3d, "safety_critical_recall": safety_recall, "mean_iou_3d": round(float(np.mean(ious)), 4) if ious else None, "mean_position_error": round(float(np.mean(pos_errs)), 4) if pos_errs else None, "mean_orientation_error_deg": round(float(np.mean(yaw_errs)), 4) if yaw_errs else None, "idf1": idf1, "id_swap_rate": id_swap_rate, "fragmentation_rate": frag_rate, "anomaly_rate": round(float(np.mean(anomaly_flags)), 4) if anomaly_flags else 0.0, "grader_consensus": round(float(np.mean(consensus_vals)), 4) if consensus_vals else None, } per_class = [] for cls in ("pedestrian", "cyclist", "vehicle", "motorcycle", "truck"): s = _match_stats(store, dataset_id, class_name=cls) if s["gt_total"] == 0 and s["n_annotations"] == 0: continue p = _prf(s) if gt_available else {"precision": None, "recall": None, "f1": None} per_class.append({"class_name": cls, **p, "support": s["gt_total"]}) per_scenario = [] for scn in store.where("scenarios", dataset_id=dataset_id): fids = set(scn.frame_ids) s = _match_stats(store, dataset_id, frame_ids=fids) p = _prf(s) if gt_available else {"precision": None, "recall": None, "f1": None} per_scenario.append({"scenario": scn.scenario_type, **p, "support": s["gt_total"]}) return { "dataset_id": dataset_id, "gt_available": gt_available, "gt_type": dataset.gt_type if gt_available else None, "gt_coverage": dataset.gt_coverage, "global": glob, "per_class": per_class, "per_scenario": per_scenario, } def _map_3d(store: EvalStore, dataset_id: str, max_frames: int = 40) -> Optional[float]: """Mean AP over IoU thresholds {0.5, 0.7}, averaged over sampled frames.""" from sensorflow.metrics.perception_3d import compute_map_mar frames = sorted(store.where("frames", dataset_id=dataset_id), key=lambda f: f.index) if not frames: return None step = max(1, len(frames) // max_frames) sampled = frames[::step] anns_by_frame: Dict[str, List] = defaultdict(list) for a in store.where("annotations", dataset_id=dataset_id): if a.status != "REJECTED" and a.bbox_3d: anns_by_frame[a.frame_id].append(a.bbox_3d) aps = [] for f in sampled: gts = [g.bbox_3d for g in f.gt_boxes] preds = anns_by_frame.get(f.frame_id, []) if not gts and not preds: continue m = compute_map_mar(preds, gts) aps.append(m["map_3d"]) return round(float(np.mean(aps)), 4) if aps else None # ------------------------------------------------------------------ counters / funnel def counters(store: EvalStore, dataset_id: Optional[str] = None) -> Dict[str, int]: anns = store.where("annotations", dataset_id=dataset_id) if dataset_id else store.all("annotations") frames = store.where("frames", dataset_id=dataset_id) if dataset_id else store.all("frames") evaluated = sum(1 for a in anns if store.get("triage_decisions", a.annotation_id) is not None) decisions = [store.get("triage_decisions", a.annotation_id) for a in anns] auto_graded = sum(1 for d in decisions if d is not None and d.status == "AUTO_GRADED") open_tasks = [t for t in store.all("review_tasks") if t.status != "resolved" and (dataset_id is None or t.dataset_id == dataset_id)] events = store.where("rare_events", dataset_id=dataset_id) if dataset_id else store.all("rare_events") return { "frames_processed": len(frames), "auto_labeled": len(anns), "evaluated": evaluated, "auto_graded": auto_graded, "flagged": sum(1 for a in anns if a.status == "FLAGGED"), "in_hitl": len(open_tasks), "verified": sum(1 for a in anns if a.status == "VERIFIED"), "rejected": sum(1 for a in anns if a.status == "REJECTED"), "rare_events": len(events), } def funnel(store: EvalStore, dataset_id: Optional[str] = None) -> Dict: c = counters(store, dataset_id) anns = store.where("annotations", dataset_id=dataset_id) if dataset_id else store.all("annotations") validated = sum(1 for a in anns if store.get("validations", a.annotation_id) is not None) tds = store.all("training_datasets") if dataset_id: tds = [t for t in tds if t.source_dataset_id == dataset_id] in_training = sum(t.num_verified_labels for t in tds) tasks = [t for t in store.all("review_tasks") if dataset_id is None or t.dataset_id == dataset_id] resolved = [t for t in tasks if t.status == "resolved"] relabeled = [t for t in resolved if t.resolution and t.resolution.action in ("correct", "approve", "merge_tracks", "split_track")] revalidated = [t for t in relabeled if t.resolution.revalidation_passed is not None] re_verified = [t for t in relabeled if t.resolution.final_status == "VERIFIED"] base = max(c["auto_labeled"], 1) def stage(name: str, count: int) -> Dict: return {"stage": name, "count": count, "pct_of_input": round(100.0 * count / base, 1)} main = [ stage("RAW SENSOR DATA (frames)", c["frames_processed"]), stage("AUTO-GENERATED LABELS", c["auto_labeled"]), stage("EVALUATED", c["evaluated"]), stage("QUALITY VALIDATION", validated), stage("AUTO-GRADED", c["auto_graded"]), stage("VERIFIED", c["verified"]), stage("TRAINING", in_training), ] side = [ stage("FLAGGED", c["flagged"] + len(resolved)), stage("HITL REVIEW", len(tasks)), stage("RE-LABELING", len(relabeled)), stage("RE-VALIDATION", len(revalidated)), stage("VERIFIED (post-HITL)", len(re_verified)), ] return {"main_path": main, "side_path": side} # ------------------------------------------------------------------ groups GROUP_NAMES = ["verified", "non_verified", "hitl", "rejected"] def _group_members(store: EvalStore, dataset_id: str) -> Dict[str, List]: anns = store.where("annotations", dataset_id=dataset_id) open_hitl = {t.annotation_id for t in store.all("review_tasks") if t.dataset_id == dataset_id and t.status != "resolved"} groups: Dict[str, List] = {g: [] for g in GROUP_NAMES} for a in anns: if a.status == "VERIFIED": groups["verified"].append(a) elif a.status == "REJECTED": groups["rejected"].append(a) elif a.annotation_id in open_hitl: groups["hitl"].append(a) else: groups["non_verified"].append(a) return groups def quality_groups(store: EvalStore, dataset_id: str) -> Dict: groups = _group_members(store, dataset_id) total = sum(len(v) for v in groups.values()) out = [] for name in GROUP_NAMES: members = groups[name] out.append({ "group_id": f"{dataset_id}:{name}", "dataset_id": dataset_id, "name": name, "count": len(members), "pct": round(100.0 * len(members) / max(total, 1), 1), }) return { "dataset_id": dataset_id, "total": total, "verification_rate": round(len(groups["verified"]) / max(total, 1), 4), "groups": out, } def group_detail(store: EvalStore, group_id: str) -> Optional[Dict]: if ":" not in group_id: return None dataset_id, name = group_id.rsplit(":", 1) groups = _group_members(store, dataset_id) if name not in groups: return None members = groups[name] total = sum(len(v) for v in groups.values()) ious, cons, anom, tq = [], [], [], [] reason_counts: Dict[str, int] = defaultdict(int) tp = fp = 0 for a in members: v = store.get("validations", a.annotation_id) if v and v.iou_3d is not None: ious.append(v.iou_3d) if v.iou_3d >= TP_IOU: tp += 1 else: fp += 1 elif v: fp += 1 g = store.get("grader_comparisons", a.annotation_id) if g and g.consensus is not None: cons.append(g.consensus) an = store.get("anomalies", a.annotation_id) if an: anom.append(an.score) t = store.get("tracking_evidence", a.annotation_id) if t and t.track_quality is not None: tq.append(t.track_quality) d = store.get("triage_decisions", a.annotation_id) if d: for r in d.failure_reasons: reason_counts[r] += 1 dataset = store.get("datasets", dataset_id) gt_available = dataset is not None and dataset.gt_coverage > 0 precision = round(tp / (tp + fp), 4) if gt_available and (tp + fp) > 0 else None # Group-level recall vs all reference objects claimed by this group's labels. matched_gt = {a.matched_gt_id for a in members if a.matched_gt_id} recall = round(tp / max(len(matched_gt), 1), 4) if gt_available and matched_gt else None f1 = None if precision is not None and recall is not None and precision + recall > 0: f1 = round(2 * precision * recall / (precision + recall), 4) mean = lambda arr: round(float(np.mean(arr)), 4) if arr else None return { "group_id": group_id, "dataset_id": dataset_id, "name": name, "count": len(members), "pct": round(100.0 * len(members) / max(total, 1), 1), "precision": precision, "recall": recall, "f1": f1, "mean_iou_3d": mean(ious), "mean_consensus": mean(cons), "mean_anomaly_score": mean(anom), "tracking_quality": mean(tq), "failure_reason_counts": dict(reason_counts), "annotation_ids": [a.annotation_id for a in members][:500], } # ------------------------------------------------------------------ haystack def haystack(store: EvalStore, dataset_id: Optional[str] = None) -> List[Dict]: """2D embedding of all observations: normals, anomalies, rare events, detected FP/FN and verified labels. Clicking a point opens its evidence.""" if dataset_id is None: datasets = sorted(store.all("datasets"), key=lambda d: d.created_at) if not datasets: return [] dataset_id = datasets[-1].dataset_id X, ids = synthetic.annotation_features(store, dataset_id) if len(ids) == 0: return [] Xs = (X - X.mean(axis=0)) / (X.std(axis=0) + 1e-9) _, _, vt = np.linalg.svd(Xs, full_matrices=False) proj = Xs @ vt[:2].T # scale to [2, 98] lo, hi = proj.min(axis=0), proj.max(axis=0) span = np.maximum(hi - lo, 1e-9) coords = 2 + 96 * (proj - lo) / span anns = {a.annotation_id: a for a in store.where("annotations", dataset_id=dataset_id)} rare_frames: Dict[str, str] = {} for e in store.where("rare_events", dataset_id=dataset_id): for fid in e.evidence_frames: rare_frames[fid] = e.event_id points: List[Dict] = [] frame_positions: Dict[str, List[np.ndarray]] = defaultdict(list) for j, aid in enumerate(ids): a = anns[aid] an = store.get("anomalies", aid) d = store.get("triage_decisions", aid) v = store.get("validations", aid) frame_positions[a.frame_id].append(coords[j]) if a.matched_gt_id is None and a.status in ("FLAGGED", "REJECTED"): cat = "false_positive" elif v and v.iou_3d is not None and v.iou_3d < TP_IOU and a.status in ("FLAGGED", "REJECTED"): cat = "false_positive" elif an and an.is_anomaly: cat = "anomaly" elif a.status == "VERIFIED" and a.source != "auto": cat = "verified" elif a.status == "VERIFIED": cat = "normal" elif d is not None and d.status == "FLAGGED": cat = "anomaly" if (an and an.score > 0.7) else "normal" else: cat = "normal" points.append({ "id": aid, "x": round(float(coords[j][0]), 2), "y": round(float(coords[j][1]), 2), "category": cat, "anomaly_score": round(float(an.score), 4) if an else 0.0, "class_name": a.class_name, "frame_id": a.frame_id, "kind": "annotation", }) # Missed objects (false negatives): reference GT never matched by a label. matched = {a.matched_gt_id for a in anns.values() if a.matched_gt_id} rng = np.random.default_rng(13) for f in store.where("frames", dataset_id=dataset_id): for g in f.gt_boxes: if g.gt_id in matched: continue base = np.mean(frame_positions[f.frame_id], axis=0) if frame_positions.get(f.frame_id) else np.array([50.0, 50.0]) jitter = rng.normal(0, 3, 2) points.append({ "id": f"fn-{g.gt_id}", "x": round(float(np.clip(base[0] + jitter[0], 1, 99)), 2), "y": round(float(np.clip(base[1] + jitter[1], 1, 99)), 2), "category": "false_negative", "anomaly_score": 0.0, "class_name": g.class_name, "frame_id": f.frame_id, "kind": "annotation", }) # Rare events as first-class points near their evidence cluster. for e in store.where("rare_events", dataset_id=dataset_id): pos = [np.mean(frame_positions[fid], axis=0) for fid in e.evidence_frames if frame_positions.get(fid)] base = np.mean(pos, axis=0) if pos else np.array([90.0, 90.0]) points.append({ "id": e.event_id, "x": round(float(np.clip(base[0] + 1.5, 1, 99)), 2), "y": round(float(np.clip(base[1] + 1.5, 1, 99)), 2), "category": "rare_event", "anomaly_score": e.anomaly_score, "class_name": e.scenario_type, "frame_id": e.evidence_frames[0] if e.evidence_frames else "", "kind": "rare_event", }) return points # ------------------------------------------------------------------ evaluation record def evaluation_record(store: EvalStore, annotation_id: str) -> Optional[Dict]: a = store.get("annotations", annotation_id) if a is None: return None frame = store.get("frames", a.frame_id) gt = None if frame is not None and a.matched_gt_id: gt = next((g for g in frame.gt_boxes if g.gt_id == a.matched_gt_id), None) v = store.get("validations", annotation_id) an = store.get("anomalies", annotation_id) g = store.get("grader_comparisons", annotation_id) t = store.get("tracking_evidence", annotation_id) d = store.get("triage_decisions", annotation_id) return { "annotation_id": annotation_id, "dataset_id": a.dataset_id, "frame_id": a.frame_id, "object_class": a.class_name, "model_version": a.model_version, "ground_truth_id": a.matched_gt_id, "ground_truth_type": gt.gt_type if gt else None, "detection": {"confidence": a.confidence}, "geometry": { "iou_3d": v.iou_3d if v else None, "position_error": v.position_error if v else None, "orientation_error_deg": v.orientation_error_deg if v else None, "dimension_error": v.dimension_error if v else None, "point_density": v.point_density if v else None, "point_in_box_ratio": v.point_in_box_ratio if v else None, "ground_contact_error": v.ground_contact_error if v else None, }, "tracking": { "id_switch": t.id_switch if t else False, "fragmentation": t.fragmentation if t else False, "track_quality": t.track_quality if t else None, }, "anomaly": { "score": an.score if an else 0.0, "is_anomaly": an.is_anomaly if an else False, "detector_scores": an.detector_scores if an else {}, "normalized_scores": an.normalized_scores if an else {}, "ensemble_strategy": an.ensemble_strategy if an else "weighted_average", "decision_threshold": an.decision_threshold if an else 0.9, }, "grading": { "consensus": g.consensus if g else None, "class_agreement": g.class_agreement if g else None, "spatial_agreement": g.spatial_agreement if g else None, "temporal_agreement": g.temporal_agreement if g else None, "grader_count": g.grader_count if g else 0, "disagreement_types": g.disagreement_types if g else [], }, "validation": { "passed": v.passed if v else False, "checks": [c.model_dump() for c in v.checks] if v else [], }, "decision": d.model_dump() if d else None, "injected_errors": a.injected_errors, } # ------------------------------------------------------------------ frame summary def frame_summary(store: EvalStore, frame_id: str, max_points: int = 900) -> Optional[Dict]: f = store.get("frames", frame_id) if f is None: return None pts = synthetic.frame_points(store, f) if len(pts) > max_points: idx = np.linspace(0, len(pts) - 1, max_points).astype(int) pts = pts[idx] anns = store.where("annotations", frame_id=frame_id) return { "frame_id": f.frame_id, "sequence_id": f.sequence_id, "scene_id": f.scene_id, "timestamp_us": f.timestamp_us, "ego_pose": {"x": f.ego_pose.x, "y": f.ego_pose.y, "z": f.ego_pose.z, "yaw": f.ego_pose.yaw, "speed_mps": f.ego_pose.speed_mps}, "num_lidar_points": f.num_lidar_points, "camera": {"width": f.camera_width, "height": f.camera_height}, "annotations": [a.model_dump() for a in anns], "gt_boxes": [{ "gt_id": g.gt_id, "class_name": g.class_name, "bbox_3d": g.bbox_3d, "bbox_2d": g.bbox_2d, "gt_type": g.gt_type, } for g in f.gt_boxes], "lidar_points_bev": [[round(float(p[0]), 2), round(float(p[1]), 2), round(float(p[2]), 2)] for p in pts], } # ------------------------------------------------------------------ benchmark of techniques TECH_PU_FACTORS = { "knn": 0.4, "lof": 0.5, "isolation_forest": 0.7, "ocsvm": 0.9, "dbscan": 0.5, "autoencoder": 1.4, "vae": 1.1, "gan": 1.0, "few_shot": 0.8, "ensemble_majority_vote": 3.2, "ensemble_weighted_average": 3.2, "ensemble_meta_classifier": 3.6, } def benchmark_techniques(store: EvalStore, dataset_id: Optional[str], anomaly_config: Dict) -> Benchmark: """Comparative benchmark: each technique + the three ensembles, evaluated against the injected-defect ground truth of the synthetic dataset.""" from sensorflow.evaluation.detectors import AnomalyEnsemble, normalize_scores if dataset_id is None: datasets = sorted(store.all("datasets"), key=lambda d: d.created_at) if not datasets: raise ValueError("No dataset available to benchmark") dataset_id = datasets[-1].dataset_id dataset = store.get("datasets", dataset_id) X, ids = synthetic.annotation_features(store, dataset_id) if len(ids) < 20: raise ValueError("Not enough labels to benchmark") anns = {a.annotation_id: a for a in store.where("annotations", dataset_id=dataset_id)} y = np.array([1.0 if anns[i].injected_errors else 0.0 for i in ids]) rare_fids = {fid for e in store.where("rare_events", dataset_id=dataset_id) for fid in e.evidence_frames} in_rare = np.array([1.0 if anns[i].frame_id in rare_fids else 0.0 for i in ids]) id_sw = np.array([1.0 if "ID_SWITCH" in anns[i].injected_errors else 0.0 for i in ids]) pos_err = np.array([ (store.get("validations", i).position_error or 0.0) if store.get("validations", i) else 0.0 for i in ids]) consensus = np.array([ (store.get("grader_comparisons", i).consensus or 0.0) if store.get("grader_comparisons", i) else 0.0 for i in ids]) cfg = dict(anomaly_config) # Enable everything for a complete benchmark table. full_cfg = { **cfg, "detectors": {k: {**v, "enabled": True} for k, v in cfg.get("detectors", {}).items()}, "deep": {**cfg.get("deep", {}), "autoencoder": {**cfg.get("deep", {}).get("autoencoder", {}), "enabled": True}, "vae": {**cfg.get("deep", {}).get("vae", {}), "enabled": True}, "gan": {"enabled": True}}, "advanced": {**cfg.get("advanced", {}), "few_shot": {**cfg.get("advanced", {}).get("few_shot", {}), "enabled": True}}, } ensemble = AnomalyEnsemble(full_cfg, seed=dataset.seed if dataset else 7) _, raw, norm = ensemble.run(X, supervision=y) contamination = max(y.mean(), 0.02) k = int(round(contamination * len(y))) def evaluate(scores: np.ndarray, technique: str) -> BenchmarkResult: order = np.argsort(-scores) detected = np.zeros(len(scores)) detected[order[:k]] = 1.0 tp = float((detected * y).sum()) fp = float((detected * (1 - y)).sum()) fn = float(((1 - detected) * y).sum()) tn = float(((1 - detected) * (1 - y)).sum()) precision = tp / (tp + fp) if tp + fp else 0.0 recall = tp / (tp + fn) if tp + fn else 0.0 f1 = 2 * precision * recall / (precision + recall) if precision + recall else 0.0 rare_mask = (in_rare * y) > 0 rare_recall = float((detected[rare_mask]).mean()) if rare_mask.any() else recall missed = detected == 0 box_err = float(pos_err[missed & (y > 0)].mean()) if (missed & (y > 0)).any() else 0.0 residual_swaps = float(id_sw[missed].sum() / max(id_sw.sum(), 1)) cons = float(consensus[missed].mean()) if missed.any() else 0.0 pu = int(len(ids) * TECH_PU_FACTORS.get(technique, 1.0)) return BenchmarkResult( technique=technique, precision=round(precision, 4), recall=round(recall, 4), rare_recall=round(rare_recall, 4), f1=round(f1, 4), box_error_3d=round(box_err, 4), id_swap_rate=round(residual_swaps, 4), consensus=round(cons, 4), process_units=pu, fp_rate=round(fp / (fp + tn) if fp + tn else 0.0, 4), ) rows = [evaluate(normalize_scores(raw[name]), name) for name in raw] for strategy in ("majority_vote", "weighted_average", "meta_classifier"): e2 = AnomalyEnsemble({**full_cfg, "advanced": {**full_cfg["advanced"], "ensemble_strategy": strategy}}, seed=dataset.seed if dataset else 7) s, _, _ = e2.run(X, supervision=y) rows.append(evaluate(np.asarray(s), f"ensemble_{strategy}")) highlights = { "best_rare_recall": max(rows, key=lambda r: r.rare_recall).technique, "best_safety_recall": max(rows, key=lambda r: r.recall).technique, "lowest_fp_rate": min(rows, key=lambda r: r.fp_rate).technique, "lowest_process_units": min(rows, key=lambda r: r.process_units).technique, "lowest_tracking_error": min(rows, key=lambda r: r.id_swap_rate).technique, } bench = Benchmark(benchmark_id=new_id("bench"), dataset_id=dataset_id, rows=rows, highlights=highlights) store.put("benchmarks", bench) store.audit("benchmark_run", "Benchmark", bench.benchmark_id, f"{len(rows)} techniques on {dataset_id}") return bench # ------------------------------------------------------------------ overview def overview(store: EvalStore, pipeline) -> Dict: dataset_id = pipeline.active_dataset c = counters(store, dataset_id) m = quality_metrics(store, dataset_id)["global"] total = max(c["auto_labeled"], 1) pu = usage_summary(store) models = sorted(store.all("models"), key=lambda x: x.created_at) return { "counters": c, "metrics": m, "verification_rate": round(c["verified"] / total, 4), "automation_rate": round(c["auto_graded"] / total, 4), "process_units_total": pu["total"], "active_dataset": dataset_id, "active_model": models[-1].model_version if models else "model-v1", }