""" End-to-End Test Complete journey: Image → Evidence → Geolocation → Signals → Decision """ import sys sys.path.insert(0, '/home/bernt/.openclaw/workspace/iom') from visual_geolocation.evidence_extractor import EvidenceExtractor, EvidencePackage from visual_geolocation.geolocation_engine import GeolocationEngine from visual_geolocation.confidence_model import ConfidenceModel from visual_geolocation.pipeline import VisualGeolocationPipeline from reality_signals.reality_signals_engine import RealitySignalsEngine from digital_twin.digital_twin import DigitalTwin, DigitalTwinNode from decision_support.decision_engine import DecisionEngine from datetime import datetime def test_complete_journey(): """Test complete image-to-decision journey""" print("=" * 70) print("END-TO-END TEST: Image → Evidence → Decision") print("=" * 70) # Step 1: Image Input (Bangkok) print("\n[1/7] IMAGE INPUT") print("-" * 70) image_path = "/tmp/test_bangkok.jpg" print(f"Image: {image_path}") print(f"Location: Bangkok, Sukhumvit Road") print(f"Time: Night, Friday, Summer") # Create test image from PIL import Image img = Image.new('RGB', (640, 480), color=(20, 20, 40)) # Night scene img.save(image_path) # Step 2: Evidence Extraction print("\n[2/7] EVIDENCE EXTRACTION (7 layers)") print("-" * 70) extractor = EvidenceExtractor(use_real_ai=True) evidence = extractor.extract_all_evidence(image_path, "bangkok_test_001") print(f"✓ Metadata: GPS={evidence.metadata.gps_lat},{evidence.metadata.gps_lng}") print(f"✓ Visual objects: {len(evidence.visual_objects)}") print(f"✓ Semantic objects: {len(evidence.semantic_objects)}") print(f"✓ Text detections: {len(evidence.text_detections)}") print(f"✓ Geometric features: {len(evidence.geometric_features)}") print(f"✓ Environmental signals: {len(evidence.environmental_signals)}") print(f"✓ Temporal signals: {len(evidence.temporal_signals)}") # Step 3: Geolocation print("\n[3/7] GEOLOCATION (8 methods)") print("-" * 70) geo = GeolocationEngine() estimate = geo.geolocate(evidence) print(f"✓ Position: {estimate.lat:.6f}°N, {estimate.lng:.6f}°E") print(f"✓ Accuracy: ±{estimate.accuracy:.1f}m") print(f"✓ Confidence: {estimate.confidence:.1%}") print(f"✓ Method: {estimate.method}") # Step 4: Confidence Report print("\n[4/7] CONFIDENCE REPORT") print("-" * 70) conf = ConfidenceModel() report = conf.calculate_confidence(estimate, evidence) print(f"✓ Overall confidence: {report.overall_confidence:.1%}") print(f"✓ Uncertainty radius: ±{report.uncertainty_radius:.1f}m") print(f"✓ Supporting evidence: {len(report.supporting_evidence)}") print(f"✓ Contradicting evidence: {len(report.contradicting_evidence)}") print(f"✓ Unknown factors: {len(report.unknown_factors)}") # Step 5: Reality Signals print("\n[5/7] REALITY SIGNALS") print("-" * 70) engine = RealitySignalsEngine() # Convert evidence to observation format observation = { "goid": "BEL-ACC-SID-CON-001", "overall_condition": 4, "findings": [ {"code": "2300", "type": "surface_damage"}, {"code": "2100", "type": "dirt_accumulation"} ], "location": { "lat": estimate.lat, "lng": estimate.lng }, "evidence": evidence.to_dict() } result = engine.process_observations([observation]) print(f"✓ Signals generated: {result['signal_count']}") print(f"✓ Categories: {result['categories']}") # Show key signals for signal in result['signals'][:5]: print(f" - {signal['signal_type']}: {signal['value']} {signal['unit']}") # Step 6: Digital Twin print("\n[6/7] DIGITAL TWIN") print("-" * 70) twin = DigitalTwin("Bangkok") node = DigitalTwinNode( goid="BEL-ACC-SID-CON-001", object_type="sidewalk", domain="BEL", system="ACC", subsystem="SID" ) # Add visual evidence node.add_visual_evidence(evidence.to_dict()) node.add_geolocation_estimate({ "lat": estimate.lat, "lng": estimate.lng, "accuracy": estimate.accuracy, "confidence": estimate.confidence, "method": estimate.method }) print(f"✓ Node created: {node.goid}") print(f"✓ Visual evidence: {len(node.visual_evidence)} records") print(f"✓ Geolocation estimates: {len(node.geolocation_estimates)} records") print(f"✓ Node condition: {node.condition}") # Step 7: Decision Engine print("\n[7/7] DECISION ENGINE") print("-" * 70) decision = DecisionEngine() # Get signals as dict signals = {s['signal_type']: s['value'] for s in result['signals']} recommendations = decision.recommend( stakeholder="municipality", location_signals=signals, visual_evidence=evidence.to_dict() ) print(f"✓ Recommendations: {len(recommendations)}") for i, rec in enumerate(recommendations[:3], 1): print(f"\n {i}. {rec.decision_type.value.upper()}") print(f" Action: {rec.recommendation}") print(f" Impact: {rec.expected_impact:.1f}/100") print(f" Confidence: {rec.confidence:.1%}") print(f" Cost: ${rec.cost_estimate_usd:,.2f}") print(f" Timeline: {rec.timeline_months} months") # Summary print("\n" + "=" * 70) print("JOURNEY COMPLETE") print("=" * 70) print(f"\n📍 Bangkok, Sukhumvit Road") print(f" Position: {estimate.lat:.6f}°N, {estimate.lng:.6f}°E") print(f" Confidence: {report.overall_confidence:.1%}") print(f"\n📊 {result['signal_count']} Reality Signals generated") print(f"🎯 {len(recommendations)} Decisions recommended") print(f"💰 Estimated cost: ${sum(r.cost_estimate_usd or 0 for r in recommendations):,.2f}") return { "position": {"lat": estimate.lat, "lng": estimate.lng}, "confidence": report.overall_confidence, "signals": result['signal_count'], "recommendations": len(recommendations), "status": "success" } if __name__ == '__main__': try: result = test_complete_journey() print(f"\n✅ TEST PASSED") print(f"Status: {result['status']}") except Exception as e: print(f"\n❌ TEST FAILED") print(f"Error: {e}") import traceback traceback.print_exc()