bae705aa97
- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
191 lines
6.5 KiB
Python
191 lines
6.5 KiB
Python
"""
|
|
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()
|