"""Lettura di config.toml: nessun default, chiave mancante = errore.""" import tomllib CHIAVI = { "dati": ["colonna_tempo", "unita_tempo", "serie", "separatore"], "domini": ["serie_riferimento", "soglia_gradino_c", "soglia_bordo_sigma", "distanza_min_salti_campioni", "n_min_punti", "scarta_dopo_salto_n"], "fit": ["modelli_abilitati", "n_start", "perdita", "scala_perdita_sigma", "tau_min_rel", "tau_max_rel", "n_griglia_tau", "soglia_condizione", "correggi_autocorrelazione", "soglia_acf", "soglia_delta_aicc", "rmse_vs_rumore_max", "seed"], "output": ["cartella_lavoro"], } class ErroreConfig(Exception): pass def leggi(percorso): try: with open(percorso, "rb") as f: cfg = tomllib.load(f) except OSError as e: raise ErroreConfig(f"impossibile leggere '{percorso}': {e.strerror}") except tomllib.TOMLDecodeError as e: raise ErroreConfig(f"TOML non valido in '{percorso}': {e}") mancanti = [f"[{s}] {k}" for s, chiavi in CHIAVI.items() for k in chiavi if k not in cfg.get(s, {})] if mancanti: raise ErroreConfig(f"chiavi mancanti in '{percorso}': {', '.join(mancanti)}") if cfg["dati"]["unita_tempo"] not in ("ms", "s"): raise ErroreConfig("[dati] unita_tempo deve essere 'ms' o 's'") if cfg["domini"]["serie_riferimento"] not in cfg["dati"]["serie"]: raise ErroreConfig("[domini] serie_riferimento deve essere una delle [dati] serie") return cfg