Download ml/scripts/final_demo.py from PRiyanshu0-1/TrackChain: direct link, hf CLI and curl.
- Browser
- Download file 5.48 kB
-
https://huggingface.co/PRiyanshu0-1/TrackChain/resolve/main/ml/scripts/final_demo.py
- Command line
-
hf download hf://PRiyanshu0-1/TrackChain/ml/scripts/final_demo.py
-
curl -L -o final_demo.py https://huggingface.co/PRiyanshu0-1/TrackChain/resolve/main/ml/scripts/final_demo.py
5.48 kB
| """ | |
| ml/scripts/final_demo.py | |
| TrackChain Capstone End-to-End Demo Walkthrough (Phase 2.7 tc.v1 SOTA). | |
| Demonstrates the full 5-model multi-modal intelligence stack running in real-time across a 100-meter railway inspection run. | |
| """ | |
| import sys | |
| import time | |
| import json | |
| from pathlib import Path | |
| import numpy as np | |
| # Add repo root to path | |
| repo_root = Path(__file__).resolve().parent.parent.parent | |
| if str(repo_root) not in sys.path: | |
| sys.path.insert(0, str(repo_root)) | |
| from ml.core.schema import ( | |
| TrackSegment, | |
| DecisionType, | |
| SeverityLevel, | |
| SignalType, | |
| DefectClass, | |
| ) | |
| from ml.inference.pipeline import TrackChainMLPipeline | |
| from ml.fusion.rules import TrackChainFusionEngine | |
| def run_capstone_demo(n_segments: int = 5): | |
| print("=" * 80) | |
| print("🚂 TrackChain Multi-Modal Edge Intelligence Stack — Live Capstone Demo") | |
| print(" Architecture: 5-Model Triad (YOLOv8 + PatchCore + EN13848 + Bi-LSTM + Seq-VAE)") | |
| print(" Contract: tc.v1 Unified [0.0, 1.0] Calibration & Cross-Modal Rule Engine") | |
| print("=" * 80) | |
| print("\n[1/4] Initializing ML Pipeline and loading models...") | |
| start_init = time.time() | |
| pipeline = TrackChainMLPipeline( | |
| fusion_engine=TrackChainFusionEngine(persistence_window=2, known_threshold=0.50, novel_threshold=0.50), | |
| conditional_typing=False, | |
| ) | |
| print(f" Pipeline initialized in {(time.time() - start_init):.2f}s") | |
| print("\n[2/4] Generating synthetic 100m railway inspection run (5 segments)...") | |
| segments = [] | |
| scenarios = [ | |
| ("Clean Track", False, 0.0, "mainline_standard"), | |
| ("Missing Fastener (Visual Known)", True, 0.0, "mainline_standard"), | |
| ("Clean Track (Post-Repair)", False, 0.0, "mainline_standard"), | |
| ("Track Twist Exceedance (Geometry Known)", False, 9.5, "mainline_standard"), | |
| ("Compound Defect: Crack + Gauge Spread (Dual Stream)", True, 14.0, "mainline_high_speed"), | |
| ] | |
| for idx, (scenario_name, has_visual_defect, vert_dip_mm, sec_type) in enumerate(scenarios): | |
| start_m = idx * 20.0 | |
| end_m = (idx + 1) * 20.0 | |
| n_bins = 80 | |
| # Frame | |
| frame = np.zeros((480, 640, 3), dtype=np.uint8) | |
| frame[200:280, :] = 120 | |
| if has_visual_defect: | |
| frame[220:260, 300:340] = 255 # Defect | |
| # Telemetry | |
| vertical = np.random.normal(0.0, 0.2, n_bins) | |
| if vert_dip_mm > 0: | |
| vertical[30:50] = vert_dip_mm | |
| gauge = np.full(n_bins, 1676.0) | |
| if idx == 4: | |
| gauge[35:45] = 1684.0 # Gauge widening +8mm | |
| telemetry = { | |
| "roll_rad": np.zeros(n_bins), | |
| "lateral_pos_mm": np.random.normal(0.0, 0.3, n_bins), | |
| "vertical_pos_mm": vertical, | |
| "gauge_mm": gauge, | |
| } | |
| seg = TrackSegment( | |
| segment_id=f"seg-{int(start_m):04d}-{int(end_m):04d}", | |
| chainage_start_m=start_m, | |
| chainage_end_m=end_m, | |
| frames=[frame], | |
| telemetry=telemetry, | |
| section_type=sec_type, | |
| ) | |
| segments.append((scenario_name, seg)) | |
| print(f" Created {len(segments)} test segments.") | |
| print("\n[3/4] Processing live inspection stream across all 5 models & fusion...") | |
| print("-" * 80) | |
| print(f"{'Chainage (m)':<15} | {'Scenario':<25} | {'Decision':<14} | {'Severity':<9} | {'Latency':<8}") | |
| print("-" * 80) | |
| demo_results = [] | |
| total_time = 0.0 | |
| for scenario_name, seg in segments: | |
| t0 = time.perf_counter() | |
| decision, signals = pipeline.process_segment(seg) | |
| dt_ms = (time.perf_counter() - t0) * 1000.0 | |
| total_time += dt_ms | |
| chainage_str = f"{seg.chainage_start_m:.1f}m - {seg.chainage_end_m:.1f}m" | |
| print(f"{chainage_str:<15} | {scenario_name:<25} | {decision.decision.value:<14} | {decision.severity.value:<9} | {dt_ms:>5.1f} ms") | |
| prim_def = decision.primary_defect | |
| prim_def_str = prim_def.value if hasattr(prim_def, "value") else str(prim_def or "none") | |
| demo_results.append({ | |
| "chainage": chainage_str, | |
| "scenario": scenario_name, | |
| "decision": decision.decision.value if hasattr(decision.decision, "value") else str(decision.decision), | |
| "severity": decision.severity.value if hasattr(decision.severity, "value") else str(decision.severity), | |
| "confidence": round(float(decision.confidence), 4), | |
| "primary_defect": prim_def_str, | |
| "action": getattr(decision, "action", "Routine inspection cycle maintained."), | |
| "latency_ms": round(dt_ms, 2), | |
| }) | |
| avg_ms = total_time / len(segments) | |
| fps = 1000.0 / avg_ms if avg_ms > 0 else 0.0 | |
| print("-" * 80) | |
| print(f"[4/4] Demo Summary: Average Pipeline Latency = {avg_ms:.1f} ms ({fps:.1f} FPS, Target >= 15 FPS)") | |
| print("=" * 80) | |
| # Save summary | |
| out_dir = repo_root / "artifacts" | |
| out_dir.mkdir(parents=True, exist_ok=True) | |
| summary_path = out_dir / "demo_run_summary.json" | |
| with open(summary_path, "w", encoding="utf-8") as f: | |
| json.dump({ | |
| "schema_version": "tc.v1", | |
| "average_latency_ms": round(avg_ms, 2), | |
| "fps": round(fps, 1), | |
| "segments": demo_results, | |
| "status": "PASSED", | |
| }, f, indent=2) | |
| print(f"\n[OK] Capstone Demo completed successfully. Report saved to: {summary_path}") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(run_capstone_demo()) | |