hackathon-ENGIN/tests/test_explainability.py
Jakub Famulski 2 82ab439452
All checks were successful
ENGIN CI / Build, test and smoke (push) Successful in 43s
ui: streamline cylinder diagnosis views
2026-08-25 13:55:56 +02:00

73 lines
3.2 KiB
Python

from __future__ import annotations
import unittest
from pathlib import Path
import pandas as pd
from engin.charts import cylinder_spectrum, deviation_chart, engine_heatmap
from engin.explainability import (
analyze_engine,
explain_cylinder,
rank_cylinders,
summarize_engine,
)
from engin.service import DiagnosisResult
ROOT = Path(__file__).resolve().parents[1]
class ExplainabilityTests(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
measurements = pd.read_csv(ROOT / "test.csv")
submission = pd.read_csv(ROOT / "predictions.csv")
diagnostics = pd.read_csv(ROOT / "prediction_diagnostics.csv")
cls.result = DiagnosisResult(measurements, submission, diagnostics)
cls.engine_id = diagnostics[diagnostics["label"].ne("ok")]["engine_id"].iloc[0]
cls.analysis = analyze_engine(cls.result, cls.engine_id)
def test_analysis_aligns_every_cylinder_and_frequency(self) -> None:
self.assertEqual(self.analysis.spectra.shape, self.analysis.reference.shape)
self.assertEqual(self.analysis.spectra.shape[1], 21)
self.assertEqual(len(self.analysis.diagnostics), len(self.analysis.measurements))
def test_health_summary_and_ranking_are_bounded(self) -> None:
summary = summarize_engine(self.analysis)
ranking = rank_cylinders(self.analysis)
self.assertEqual(len(ranking), summary.cylinders)
self.assertTrue(ranking["triage_level"].is_monotonic_decreasing)
self.assertIn(summary.highest_severity, {"nie_dotyczy", "male", "srednie", "duze"})
def test_unknown_only_engine_requires_verification(self) -> None:
engine_id = "unknown_only"
measurements = self.analysis.measurements.copy()
measurements["engine_id"] = engine_id
diagnostics = self.analysis.diagnostics.copy()
diagnostics["engine_id"] = engine_id
diagnostics["label"] = "ok"
diagnostics["severity"] = "nie_dotyczy"
diagnostics.loc[0, "label"] = "unknown"
result = DiagnosisResult(measurements, diagnostics[["engine_id", "cylinder", "label", "severity"]], diagnostics)
summary = summarize_engine(analyze_engine(result, engine_id))
self.assertEqual(summary.status, "WYMAGA WERYFIKACJI")
self.assertEqual(summary.status_tone, "unknown")
def test_cylinder_explanation_contains_actionable_evidence(self) -> None:
cylinder = int(rank_cylinders(self.analysis).iloc[0]["cylinder"])
explanation = explain_cylinder(self.analysis, cylinder)
self.assertEqual(len(explanation.top_frequencies), 3)
self.assertIn("mV", explanation.reason)
self.assertGreater(len(explanation.recommendation), 20)
def test_all_chart_factories_return_populated_figures(self) -> None:
cylinder = int(self.analysis.measurements["cylinder"].iloc[0])
compared = self.analysis.measurements["cylinder"].astype(int).head(4).tolist()
self.assertEqual(len(engine_heatmap(self.analysis).data), 1)
self.assertEqual(len(cylinder_spectrum(self.analysis, cylinder).data), 2)
self.assertEqual(
len(cylinder_spectrum(self.analysis, cylinder, compared).data),
5,
)
self.assertEqual(len(deviation_chart(self.analysis, cylinder).data), 1)