"""Basic Inference Example for Sofia Engine. Demonstrates deterministic telemetry feature extraction, statistical anomaly detection, and evidence-based diagnostic health scoring. Run: python examples/basic_inference.py """ from __future__ import annotations import numpy as np from sofia_ai.core.contracts import DataQuality, FeatureVector, SignalWindow from sofia_ai.diagnostics.engine import ( DiagnosticEngine, HealthEvent, HealthScore, compute_health_score, ) from sofia_ai.diagnostics.rules import RuleContext from sofia_ai.features import extract_from_array from sofia_ai.inference.detectors import ThresholdDetector, build_manifest_for def run_basic_inference() -> None: print("=== Sofia Engine: Basic Inference Example ===") # 1. Synthesize 1 second of vibration telemetry (fs = 1000 Hz, 25 Hz shaft rotation) fs = 1000.0 t = np.arange(1000) / fs rng = np.random.default_rng(42) # 25 Hz fundamental + 50 Hz harmonic + Gaussian background noise raw_signal = ( 0.45 * np.sin(2 * np.pi * 25.0 * t) + 0.15 * np.sin(2 * np.pi * 50.0 * t) + 0.05 * rng.normal(size=len(t)) ) print(f"Input Signal: {len(raw_signal)} samples @ {fs} Hz ({len(raw_signal)/fs:.2f} s)") # 2. Package into a validated SignalWindow window = SignalWindow( values=raw_signal, sample_rate=fs, device_id="pump-motor-01", channel="vibration_de", unit="m/s^2", quality=DataQuality.GOOD, ) # 3. Extract versioned feature vector (14 statistical + spectral metrics) features: FeatureVector = extract_from_array( window.values, window.sample_rate, channel=window.channel, quality=window.quality, ) # 4. Verify feature schema version (v3.0) features.validate_schema("3.0") print(f"Extracted FeatureVector (schema {features.schema_version}): {len(features.names)} features") for name, val in list(zip(features.names, features.values, strict=True))[:5]: print(f" - {name}: {val:.4f}") # 5. Anomaly detection via ThresholdDetector (monitoring vibration RMS) detector = ThresholdDetector(feature="rms", high=0.45) manifest = build_manifest_for(detector, model_id="rms_threshold_v1", version="1.0.0") detector.load(manifest) inference_result = detector.infer(features) print("\n--- Inference Result (Threshold Detector) ---") print(f"Monitored Feature: 'rms' = {inference_result.score:.4f} m/s^2 (high limit = 0.45)") print(f"Outcome: {inference_result.outcome.name}") print(f"Confidence: {inference_result.confidence:.2%}") # 6. Diagnostic Engine: Convert inference into evidence-backed health event diag_engine = DiagnosticEngine() context = RuleContext( device_id=window.device_id, channel=window.channel, score=inference_result.score, confidence=inference_result.confidence, unit="z-score", ) event: HealthEvent | None = diag_engine.evaluate(context) events = [event] if event else [] health_score: HealthScore = compute_health_score(events) print("\n--- Health Assessment ---") print(f"Health Score: {health_score.score:.1f} / 100.0") print(f"Credible Interval: [{health_score.lower:.1f}, {health_score.upper:.1f}]") print(f"Uncertainty: ±{health_score.uncertainty:.2%}") if event: print(f"Health Event: {event.event_type} (Severity: {event.severity.name})") print(f"Recommendation: {event.recommendation}") else: print("Status: Nominal operating condition.") if __name__ == "__main__": run_basic_inference()