Files
EquationMiner/tests/test_validazione.py
T

65 lines
2.9 KiB
Python

"""Validazione contro i parametri VERI di gen_data: extern/gen_data sorteggia i parametri di ogni corsa dal seed, quindi per ogni seed si
conoscono gradini, ampiezze e costante di tempo. Richiede extern/gen_data, che si scarica con ./scarica_gen_data.sh (altrimenti i test sono saltati)."""
import sys
import numpy as np
import pytest
from conftest import RADICE
from fitseg import dati, domini
from fitseg.analisi import analizza_domini, fit_scelto
GEN = RADICE / "extern" / "gen_data"
pytestmark = pytest.mark.skipif(not (GEN / "genera.py").exists(), reason="extern/gen_data non trovato: lancia ./scarica_gen_data.sh")
@pytest.fixture(scope="module")
def genera():
sys.path.insert(0, str(GEN))
import genera as g
yield g
sys.path.remove(str(GEN))
@pytest.mark.parametrize("seed", range(1, 21))
def test_risultati_contro_i_parametri_veri(seed, genera, cfg, tmp_path):
gcfg = genera.leggi_config(GEN / "config.toml")
veri = genera.sorteggia(gcfg, np.random.default_rng(seed))
ordine = np.argsort(veri["t_impulsi_s"])
tj = np.array(veri["t_impulsi_s"], float)[ordine]
aj = np.array(veri["dT_impulsi_c"], float)[ordine]
k = veri["k_raffreddamento_hz"]
t_ms, T, dT = genera.genera(gcfg, np.random.default_rng(seed))
with open(tmp_path / "d.csv", "w") as f:
genera.scrivi(f, t_ms, T, dT)
t, serie = dati.leggi_csv(tmp_path / "d.csv", cfg)
ris = analizza_domini(t, serie, domini.proponi(t, serie, cfg), cfg)
# gradini: numero giusto e istanti entro un paio di campioni
risc = [r for r in ris if r["tipo"] == "riscaldamento"]
assert len(risc) == len(tj)
for r, x in zip(risc, tj, strict=True):
assert abs(r["t0_s"] - x) < 0.3
for nome in serie:
raff = [r for r in ris if r["tipo"] == "raffreddamento"]
# costante di tempo del raffreddamento finale (libero)
finale = fit_scelto(raff[-1]["serie"][nome])
assert finale is not None and finale["parametri"]["tau"] * k == pytest.approx(1.0, abs=0.03)
for r in raff:
fit = fit_scelto(r["serie"][nome])
if fit is None: # indeterminato solo se i campioni sono meno del minimo
assert r["n_fit"] < cfg["domini"]["n_min_punti_parametri_fissi"]
continue
atteso = float(sum(a * np.exp(-k * (r["t0_s"] - x)) for x, a in zip(tj, aj, strict=True) if x <= r["t0_s"]))
if nome == "dT_C": # ampiezza A al netto dell'asintoto: confrontabile con la somma dei decadimenti dei gradini
assert fit["parametri"]["A"] == pytest.approx(atteso, rel=0.04)
# salti: stimati dai modelli (o dalla misura corretta con c e τ del finale) entro il 5 % dall'ampiezza vera del gradino
for r, a in zip(risc, aj, strict=True):
g = r["serie"]["dT_C"]["gradino"]
if g["stima"] in ("modelli", "misura corretta"):
assert g["delta"] == pytest.approx(a, rel=0.05)