Files
gen_data/docs/SPEC.md
T

79 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Generatore CSV `T` e `ΔT` con rumore realistico — specifica minima
**Obiettivo**: un solo script, un solo file di configurazione, un CSV con la temperatura `T` e la differenza `ΔT = T − T_amb`,
con rumore, quantizzazione e jitter dei tempi simili a un sensore IR reale.
**Assunzione da confermare**: `T` = temperatura oggetto del sensore IR, `T_amb` = temperatura ambiente dello stesso sensore
(non scritta nel CSV, serve solo per `ΔT`).
## 1. Output
```
t_ms,T_C,dT_C
150,24.50,1.80
301,24.41,1.71
```
- `t_ms`: intero; `T_C`, `dT_C`: due decimali (`passo_T_c`). Separatore `,`, fine riga `\n`.
- `ΔT` è calcolato **dopo** rumore e quantizzazione di entrambi i canali, quindi eredita il passo a gradini dell'ambiente.
## 2. Configurazione
Tutti i valori sono in [`config.toml`](../config.toml) (unica fonte: questo documento non li ripete). Gruppi:
tempi · ambiente (anche baseline di T) · rumore · gradini di riscaldamento e raffreddamento.
Nessun valore è scritto nello script: chiave mancante ⇒ errore.
## 3. Modello (5 passi)
1. **Tempi**: `t_i = t_{i−1} + dt_ms + U(−jitter_ms, +jitter_ms)`, fino a `durata_s`.
2. **T vera** = ambiente vero + eccesso termico (T parte da `T_amb`, sale con i gradini e ridiscende fino a `T_amb`):
- ambiente vero `B(t) = amb_inf + amb_A·exp(−t/τ_amb)` (stessa curva del passo 5, senza rumore né quantizzazione);
- eccesso `x(t) = Σ_j ΔT_j · exp(−k·(t − t_j))` per `t ≥ t_j` (un gradino per ogni `t_impulsi_s`, poi raffreddamento esponenziale);
- `T_vera = B + x`.
3. **Risposta del sensore**: filtro del 1° ordine `y' = (T_vera − y)/τ_sens` (griglia fine, 5 ms, poi interpolazione ai `t_i`).
4. **Rumore di T**: `T_i = y_i + w_i + σ(x_i)·N(0,1)`, con
- `σ(x) = σ + (σ_caldo − σ)·min(1, x/x_rif)`;
- `w` = deriva lenta (Ornstein-Uhlenbeck): `w_{i+1} = φ·w_i + σ_w·√(1−φ²)·N(0,1)`, `φ = exp(−Δt/τ_w)`.
Poi arrotondamento a `passo_T_c`.
5. **Ambiente e ΔT**: `amb_i = round_{amb_passo}( amb_inf + amb_A·exp(−t/τ_amb) + N(0, amb_sigma²) )`; `dT_i = round_{passo}( T_i − amb_i )`.
## 4. Uso con uv (un solo file, nessun progetto)
`genera.py` con dipendenza dichiarata in testa (PEP 723):
```python
# /// script
# requires-python = ">=3.11"
# dependencies = ["numpy"]
# ///
```
```bash
uv run genera.py config.toml -o out.csv --seed 42 # riproducibile
uv run genera.py config.toml > out.csv # seed casuale, stampato su stderr
```
Opzioni: `config` (posizionale), `-o/--output` (default stdout), `--seed` (default: casuale, stampato su stderr).
Uscita con errore (exit 1) e messaggio in italiano se manca una chiave, se `t_impulsi_s` e `dT_impulsi_c` hanno lunghezze diverse
o se il file non è scrivibile. La lettura TOML usa `tomllib` (standard library): unica dipendenza esterna `numpy`.
## 5. Controlli di accettazione (con la configurazione d'esempio)
Verificati su un prototipo (30 seed):
| Controllo | Atteso |
|---|---|
| `T` a inizio run | ≈ `T_amb` (≈ 22.65 °C) |
| Rumore a freddo: `std(diff(T))/√2` sui primi ~100 s | 0.105 – 0.115 |
| Picco di `T` | ≈ 224 °C (da ricontrollare col prototipo) |
| `T` a 134 s | ≈ 80.5 °C |
| `T` a fine run | ≈ `T_amb` (≈ 23.1 °C, entro ~0.1 °C) |
| `ΔT` a inizio run | ≈ 0 °C (solo rumore) |
| `ΔT` a fine run | ≈ 0 °C (solo rumore) |
| Intervalli `dt` | tutti in `dt_ms ± jitter_ms` |
| Stesso `--seed` e stessa config | file identico |
## 6. Limiti (accettati per semplicità)
- Un solo tempo di raffreddamento esponenziale (nessuna distinzione conduzione/convezione).
- Gradini istantanei (nessun transito sotto l'induttore e nessuna dipendenza dalla velocità).
- L'ambiente non sale quando T è alta (nessun riscaldamento dell'ambiente del sensore): `ΔT` è leggermente sovrastimato durante e subito dopo il riscaldamento.
- Nessun glitch di campionamento né disturbi a salto durante il raffreddamento.
- Rumore tarato su un solo sensore: ricalibrare `sigma_c`, `wander_*`, `amb_*` con i propri dati.