All checks were successful
ENGIN CI / Build, test and smoke (push) Successful in 43s
73 lines
3.2 KiB
Python
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)
|