59 lines
1.8 KiB
Python
59 lines
1.8 KiB
Python
# Copyright 2026 Umbra Tools (umbratools.com)
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
class QualityReport:
|
|
def __init__(self) -> None:
|
|
self.metrics: dict[str, Any] = {}
|
|
self.passed = False
|
|
|
|
def add_metric(self, name: str, value: Any, threshold: Any, passed: bool) -> None:
|
|
self.metrics[name] = {
|
|
"value": value,
|
|
"threshold": threshold,
|
|
"passed": passed,
|
|
}
|
|
|
|
def evaluate(self, config: Any) -> bool:
|
|
checks = []
|
|
|
|
if "mos_score" in self.metrics and config.min_mos:
|
|
checks.append(self.metrics["mos_score"]["value"] >= config.min_mos)
|
|
|
|
if "wer_score" in self.metrics and config.max_wer:
|
|
checks.append(self.metrics["wer_score"]["value"] <= config.max_wer)
|
|
|
|
if "speaker_similarity" in self.metrics and config.min_speaker_similarity:
|
|
checks.append(
|
|
self.metrics["speaker_similarity"]["value"] >= config.min_speaker_similarity
|
|
)
|
|
|
|
self.passed = all(checks) if checks else False
|
|
return self.passed
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
return {
|
|
"metrics": self.metrics,
|
|
"passed": self.passed,
|
|
}
|
|
|
|
def save(self, output_path: Path) -> None:
|
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(output_path, "w") as f:
|
|
json.dump(self.to_dict(), f, indent=2)
|
|
|
|
@classmethod
|
|
def load(cls, path: Path) -> QualityReport:
|
|
report = cls()
|
|
with open(path) as f:
|
|
data = json.load(f)
|
|
report.metrics = data.get("metrics", {})
|
|
report.passed = data.get("passed", False)
|
|
return report
|