Parametri sorteggiati a ogni corsa: intervalli [min, max] per gradini, ambiente, rumore e salti
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0054c49a5
commit
797517db33
6 files changed
+97
-70
No files matched your search
@@ -21,7 +21,8 @@ Genera un CSV con la temperatura T di un sensore IR e la differenza dT = T - T_a
|
||||
con rumore, quantizzazione e jitter dei tempi simili a un sensore reale.
|
||||
|
||||
T parte dalla temperatura ambiente, sale con uno o più gradini di riscaldamento e
|
||||
ridiscende con raffreddamento esponenziale fino a T_amb. Ogni corsa (seed) è diversa."""
|
||||
ridiscende con raffreddamento esponenziale fino a T_amb. Ogni corsa (seed) è diversa:
|
||||
i parametri principali sono intervalli [min, max] sorteggiati a ogni corsa."""
|
||||
|
||||
EPILOGO = """\
|
||||
esempi:
|
||||
@@ -38,40 +39,56 @@ formato dell'output (separatore ',', fine riga '\\n'):
|
||||
|
||||
cosa fa (in ordine):
|
||||
1. tempi t_i = t_(i-1) + dt_ms +/- jitter_ms, fino a durata_s
|
||||
2. T vera ambiente vero + gradini di riscaldamento con raffreddamento
|
||||
esponenziale, perturbati a caso a ogni corsa + disturbi a salto
|
||||
2. T vera ambiente vero + gradini di riscaldamento (numero, istanti, ampiezze
|
||||
sorteggiati) con raffreddamento esponenziale + disturbi a salto
|
||||
3. sensore filtro del 1° ordine (tau_sensore_s) su griglia fine da 5 ms
|
||||
4. rumore di T bianco (più forte a caldo) + deriva lenta, poi quantizzazione
|
||||
5. ambiente, dT ambiente con rumore e quantizzazione propri; dT = T - ambiente
|
||||
|
||||
gruppi di chiavi di config.toml (unica fonte dei valori, unità nel suffisso:
|
||||
_s secondi, _ms millisecondi, _c gradi C, _hz 1/s; ogni chiave è obbligatoria):
|
||||
_s secondi, _ms millisecondi, _c gradi C, _hz 1/s; ogni chiave è obbligatoria).
|
||||
Le chiavi marcate [min, max] sono intervalli: a ogni corsa ne viene sorteggiato un
|
||||
valore uniforme (n_gradini: intero, estremi inclusi):
|
||||
tempi durata_s, dt_ms, jitter_ms
|
||||
ambiente amb_inf_c, amb_A_c, amb_tau_s, amb_sigma_c, amb_passo_c
|
||||
rumore di T sigma_c, sigma_caldo_c, x_rif_c, wander_sigma_c, wander_tau_s, passo_T_c
|
||||
gradini t_impulsi_s, dT_impulsi_c ([] = nessun riscaldamento; stessa lunghezza),
|
||||
k_raffreddamento_hz, tau_sensore_s
|
||||
variabilità impulsi_jitter_t_s, impulsi_jitter_amp_rel, k_jitter_rel (0 = disattivata)
|
||||
salti salti_rate_hz, salti_media_c, salti_sigma_c, salti_tau_s, salti_x_min_c,
|
||||
salti_max_c (raffreddamento); salti_risc_rate_hz, salti_risc_media_c,
|
||||
salti_risc_sigma_c, salti_risc_tau_s (riscaldamento)
|
||||
ambiente amb_inf_c [min, max], amb_A_c [min, max], amb_tau_s [min, max],
|
||||
amb_sigma_c, amb_passo_c
|
||||
rumore di T sigma_c [min, max], sigma_caldo_c [min, max], x_rif_c,
|
||||
wander_sigma_c [min, max], wander_tau_s [min, max], passo_T_c
|
||||
gradini n_gradini [min, max], t_primo_gradino_s [min, max],
|
||||
distanza_gradini_s [min, max] (tra gradini consecutivi),
|
||||
dT_gradino_c [min, max] (ampiezza di ogni gradino),
|
||||
k_raffreddamento_hz [min, max], tau_sensore_s [min, max]
|
||||
salti salti_rate_hz [min, max], salti_media_c, salti_sigma_c [min, max],
|
||||
salti_tau_s, salti_x_min_c, salti_max_c (raffreddamento);
|
||||
salti_risc_rate_hz [min, max], salti_risc_media_c,
|
||||
salti_risc_sigma_c [min, max], salti_risc_tau_s (riscaldamento)
|
||||
|
||||
codici di uscita:
|
||||
0 ok
|
||||
1 errore, con messaggio in italiano su stderr: file di configurazione illeggibile
|
||||
o TOML non valido, chiave mancante, t_impulsi_s e dT_impulsi_c di lunghezza
|
||||
diversa, file di uscita non scrivibile
|
||||
o TOML non valido, chiave mancante, intervallo [min, max] non valido,
|
||||
file di uscita non scrivibile
|
||||
2 argomenti della riga di comando non validi
|
||||
|
||||
altri strumenti: grafico.py (disegna un CSV), pulisci.sh (svuota output/).
|
||||
documentazione: docs/SPEC.md (modello e controlli), docs/FUNZIONALITA.md (funzionalità)."""
|
||||
|
||||
# chiavi che sono intervalli [min, max], sorteggiati uniformi a ogni corsa
|
||||
INTERVALLI = [
|
||||
"amb_inf_c", "amb_A_c", "amb_tau_s",
|
||||
"sigma_c", "sigma_caldo_c", "wander_sigma_c", "wander_tau_s",
|
||||
"k_raffreddamento_hz", "tau_sensore_s",
|
||||
"salti_rate_hz", "salti_sigma_c", "salti_risc_rate_hz", "salti_risc_sigma_c",
|
||||
]
|
||||
# intervalli che descrivono i gradini (istanti e ampiezze derivati da questi)
|
||||
INTERVALLI_GRADINI = ["n_gradini", "t_primo_gradino_s", "distanza_gradini_s", "dT_gradino_c"]
|
||||
|
||||
CHIAVI = [
|
||||
"durata_s", "dt_ms", "jitter_ms",
|
||||
"amb_inf_c", "amb_A_c", "amb_tau_s", "amb_sigma_c", "amb_passo_c",
|
||||
"sigma_c", "sigma_caldo_c", "x_rif_c", "wander_sigma_c", "wander_tau_s", "passo_T_c",
|
||||
"t_impulsi_s", "dT_impulsi_c", "k_raffreddamento_hz", "tau_sensore_s",
|
||||
"impulsi_jitter_t_s", "impulsi_jitter_amp_rel", "k_jitter_rel",
|
||||
"n_gradini", "t_primo_gradino_s", "distanza_gradini_s", "dT_gradino_c",
|
||||
"k_raffreddamento_hz", "tau_sensore_s",
|
||||
"salti_rate_hz", "salti_media_c", "salti_sigma_c", "salti_tau_s", "salti_x_min_c",
|
||||
"salti_max_c", "salti_risc_rate_hz", "salti_risc_media_c", "salti_risc_sigma_c", "salti_risc_tau_s",
|
||||
]
|
||||
@@ -111,8 +128,15 @@ def leggi_config(percorso):
|
||||
mancanti = [k for k in CHIAVI if k not in cfg]
|
||||
if mancanti:
|
||||
errore(f"chiavi mancanti in '{percorso}': {', '.join(mancanti)}")
|
||||
if len(cfg["t_impulsi_s"]) != len(cfg["dT_impulsi_c"]):
|
||||
errore("'t_impulsi_s' e 'dT_impulsi_c' hanno lunghezze diverse")
|
||||
for k in INTERVALLI + INTERVALLI_GRADINI:
|
||||
v = cfg[k]
|
||||
if (not isinstance(v, list) or len(v) != 2
|
||||
or not all(isinstance(x, (int, float)) and not isinstance(x, bool) for x in v)
|
||||
or v[0] > v[1]):
|
||||
errore(f"'{k}' deve essere un intervallo [min, max] con min <= max")
|
||||
n_min, n_max = cfg["n_gradini"]
|
||||
if not (isinstance(n_min, int) and isinstance(n_max, int) and n_min >= 1):
|
||||
errore("'n_gradini' deve essere un intervallo [min, max] di interi con min >= 1")
|
||||
return cfg
|
||||
|
||||
|
||||
@@ -125,13 +149,14 @@ def eccesso(t_s, cfg):
|
||||
return x
|
||||
|
||||
|
||||
def perturba(cfg, rng):
|
||||
"""Copia di cfg con istanti, ampiezze e k degli impulsi variati a caso (ogni corsa è diversa)."""
|
||||
n = len(cfg["t_impulsi_s"])
|
||||
t = np.sort(np.asarray(cfg["t_impulsi_s"], float) + cfg["impulsi_jitter_t_s"] * rng.standard_normal(n))
|
||||
d = np.asarray(cfg["dT_impulsi_c"], float) * (1 + cfg["impulsi_jitter_amp_rel"] * rng.standard_normal(n))
|
||||
k = cfg["k_raffreddamento_hz"] * (1 + cfg["k_jitter_rel"] * rng.standard_normal())
|
||||
return {**cfg, "t_impulsi_s": t, "dT_impulsi_c": d, "k_raffreddamento_hz": k}
|
||||
def sorteggia(cfg, rng):
|
||||
"""Copia di cfg con ogni intervallo sostituito da un valore sorteggiato e i gradini generati (ogni corsa è diversa)."""
|
||||
valori = {k: rng.uniform(*cfg[k]) for k in INTERVALLI}
|
||||
n = int(rng.integers(cfg["n_gradini"][0], cfg["n_gradini"][1] + 1))
|
||||
t_primo = rng.uniform(*cfg["t_primo_gradino_s"])
|
||||
t = t_primo + np.concatenate(([0.0], np.cumsum(rng.uniform(*cfg["distanza_gradini_s"], n - 1))))
|
||||
d = rng.uniform(*cfg["dT_gradino_c"], n)
|
||||
return {**cfg, **valori, "t_impulsi_s": t, "dT_impulsi_c": d}
|
||||
|
||||
|
||||
def eventi(g_s, cfg, rng, t_ini, t_fin, rate, media, sigma, tau, x_min):
|
||||
@@ -169,7 +194,7 @@ def quantizza(v, passo):
|
||||
|
||||
|
||||
def genera(cfg, rng):
|
||||
cfg = perturba(cfg, rng)
|
||||
cfg = sorteggia(cfg, rng)
|
||||
# 1. tempi
|
||||
n_max = int(cfg["durata_s"] * 1000 / (cfg["dt_ms"] - cfg["jitter_ms"])) + 2
|
||||
dt = cfg["dt_ms"] + rng.uniform(-cfg["jitter_ms"], cfg["jitter_ms"], n_max)
|
||||
|
||||
Reference in new issue
Block a user