2026-10-29 11:54:09 +01:00
|
|
|
|
"""Fixture comuni: configurazione, segnale sintetico (verità nota) e scrittura di CSV di prova."""
|
2026-10-29 10:13:01 +01:00
|
|
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
|
|
from fitseg import config
|
|
|
|
|
|
|
|
|
|
|
|
RADICE = Path(__file__).parent.parent
|
|
|
|
|
|
|
|
|
|
|
|
# verità del segnale sintetico
|
|
|
|
|
|
TAU, T_AMB = 16.0, 23.0
|
|
|
|
|
|
GRADINI = [(15.0, 80.0), (18.0, 70.0), (22.0, 60.0)] # (istante [s], ampiezza [°C])
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-10-29 11:54:09 +01:00
|
|
|
|
def scrivi_csv(percorso, t, serie):
|
|
|
|
|
|
"""CSV nel formato di gen_data (t_ms intero, valori a due decimali)."""
|
|
|
|
|
|
with open(percorso, "w") as f:
|
|
|
|
|
|
f.write("t_ms," + ",".join(serie) + "\n")
|
|
|
|
|
|
f.writelines(f"{round(ti * 1000)}," + ",".join(f"{serie[n][i]:.2f}" for n in serie) + "\n" for i, ti in enumerate(t))
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-10-29 10:13:01 +01:00
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
|
|
|
def cfg():
|
|
|
|
|
|
return config.leggi(RADICE / "config.toml")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def segnale(rumore=0.1, seed=0, gradini=GRADINI, durata=120.0, dt=0.15):
|
|
|
|
|
|
"""T(t) = ambiente + Σ ampiezza·exp(−(t−t_j)/τ) per t ≥ t_j, più rumore gaussiano: nessun disturbo a salto."""
|
|
|
|
|
|
rng = np.random.default_rng(seed)
|
|
|
|
|
|
t = np.arange(dt, durata, dt)
|
|
|
|
|
|
x = sum(a * np.exp(-(t - tj) / TAU) * (t >= tj) for tj, a in gradini) if gradini else np.zeros_like(t)
|
|
|
|
|
|
T = T_AMB + x + rumore * rng.standard_normal(len(t))
|
|
|
|
|
|
return t, {"T_C": T, "dT_C": T - T_AMB}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
|
|
|
def sintetico():
|
|
|
|
|
|
return segnale()
|