Add trace_agg/src/trace_agg/core.py
This commit is contained in:
commit
2759bd3e56
1 changed files with 56 additions and 0 deletions
56
trace_agg/src/trace_agg/core.py
Normal file
56
trace_agg/src/trace_agg/core.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
from __future__ import annotations
|
||||
import statistics
|
||||
from typing import List, Dict, Any
|
||||
|
||||
|
||||
class InvalidTraceDataError(ValueError):
|
||||
"""Raised when trace data validation fails."""
|
||||
pass
|
||||
|
||||
|
||||
def _validate_record(record: Dict[str, Any]) -> None:
|
||||
required_fields = {
|
||||
'run_id': str,
|
||||
'mischfenster_p50': (int, float),
|
||||
'mischfenster_p95': (int, float),
|
||||
'mischfenster_max': (int, float),
|
||||
'step_order_stability': (int, float),
|
||||
'read_between_steps': int
|
||||
}
|
||||
for field, ftype in required_fields.items():
|
||||
if field not in record:
|
||||
raise InvalidTraceDataError(f"Missing field '{field}' in trace record")
|
||||
if not isinstance(record[field], ftype):
|
||||
raise InvalidTraceDataError(
|
||||
f"Field '{field}' has invalid type: {type(record[field])}, expected {ftype}"
|
||||
)
|
||||
|
||||
|
||||
def generate_summary(trace_data: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||
"""Aggregiert Trace-Daten und erzeugt eine zusammengefasste JSON-Statistik pro Run."""
|
||||
assert isinstance(trace_data, list), "trace_data muss eine Liste sein."
|
||||
if not trace_data:
|
||||
raise InvalidTraceDataError("Eingabeliste trace_data darf nicht leer sein.")
|
||||
|
||||
for rec in trace_data:
|
||||
_validate_record(rec)
|
||||
|
||||
p50_values = [float(r['mischfenster_p50']) for r in trace_data]
|
||||
p95_values = [float(r['mischfenster_p95']) for r in trace_data]
|
||||
max_values = [float(r['mischfenster_max']) for r in trace_data]
|
||||
stability_values = [float(r['step_order_stability']) for r in trace_data]
|
||||
read_values = [int(r['read_between_steps']) for r in trace_data]
|
||||
|
||||
result = {
|
||||
'num_records': len(trace_data),
|
||||
'mischfenster_p50_mean': statistics.mean(p50_values),
|
||||
'mischfenster_p95_mean': statistics.mean(p95_values),
|
||||
'mischfenster_max_mean': statistics.mean(max_values),
|
||||
'mischfenster_p50_median': statistics.median(p50_values),
|
||||
'mischfenster_p95_median': statistics.median(p95_values),
|
||||
'mischfenster_max_median': statistics.median(max_values),
|
||||
'step_order_stability_avg': statistics.mean(stability_values),
|
||||
'read_between_steps_total': sum(read_values),
|
||||
}
|
||||
|
||||
return result
|
||||
Loading…
Reference in a new issue