2026-10-30 08:57:20 +01:00
"""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)."""
2026-10-29 11:54:09 +01:00
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
2026-10-30 08:57:20 +01:00
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" )
2026-10-29 11:54:09 +01:00
@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 )