- equazioni dei modelli in LaTeX, equazione scelta con i valori sostituiti (24092...24092) - parametri ± IC, sigma, RMSE, R^2, rho_1, Delta, t_0/t_1 e criteri di scelta in formula - motivo della scelta a parole (i criteri in LaTeX stanno nel report) - test sulle formule e sul bilanciamento dei dollari Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
75 lines
7.2 KiB
Markdown
75 lines
7.2 KiB
Markdown
# `fitseg` — specifica
|
||
|
||
**Obiettivo**: leggere un CSV (`t_ms,T_C,dT_C`, p.es. da `gen_data`), riconoscere **riposo**, **riscaldamento** (flusso in entrata: la salita rapida di ogni gradino, pochi campioni) e **raffreddamento** (decadimento esponenziale dopo ogni gradino), dividere il tempo in **domini** e trovare per ogni (dominio, serie) l'equazione che lo approssima meglio. Valori configurabili: solo in [`config.toml`](../config.toml). Uso: [README](../README.md).
|
||
|
||
## 1. Flusso
|
||
|
||
```
|
||
CSV ─► [1 DOMINI] gradini ⇒ riposo | (riscaldamento, raffreddamento) per ogni gradino ─► output/<csv>/01_domini/ (domini.png, domini.toml modificabile)
|
||
▼
|
||
[2 FIT] per (dominio, serie): modelli del tipo ─► regola di scelta ─► 02_sovrapposizione/ (dati contro equazioni)
|
||
▼
|
||
[3 REPORT] 03_report/report.md (immagini incorporate, formule in LaTeX) e risultati.json
|
||
```
|
||
Tutto il calcolo è deterministico (nessuna partenza casuale, nessun LLM). Ogni CSV ha la sua cartella `output/<nome csv>/`.
|
||
|
||
## 2. Domini (`domini.py`)
|
||
|
||
Struttura fisica (vedi `gen_data/docs/SPEC.md`): T parte dall'ambiente, **gradini istantanei positivi** (2–4 s uno dall'altro): la salita dura 2–3 campioni ed è il **riscaldamento**; ognuno è seguito da un decadimento esponenziale, il **raffreddamento**, che dopo l'ultimo gradino prosegue fino all'ambiente. Compaiono anche scarti casuali (±4 °C, rientro < 1 s).
|
||
|
||
1. `d = diff(y)` sulla `serie_riferimento`; gradino = `d > soglia_gradino_c`; rilevazioni più vicine di `distanza_min_salti_campioni` sono lo stesso gradino.
|
||
2. I campioni della salita formano il dominio `riscaldamento`: dal primo campione già in salita all'ultimo (si estende ai campioni adiacenti finché `d > soglia_bordo_sigma · σ_d`, σ_d = MAD dei salti).
|
||
3. Prima del primo gradino `riposo`; dopo ogni gradino `raffreddamento`, fino al gradino successivo o alla fine. Con N gradini i domini sono 1 + 2N. Senza gradini: un solo `riposo`. Un raffreddamento senza campioni (gradini adiacenti) non viene creato.
|
||
4. I primi `scarta_dopo_salto_n` campioni di ogni `raffreddamento` sono esclusi dal fit (sicurezza dopo la salita).
|
||
|
||
Ipotesi: tempo crescente; rumore circa gaussiano, σ stimato per dominio da `1.4826·MAD(d²y)/√6`; le serie condividono i domini; i gradini sono salti positivi ≫ rumore e scarti casuali (`soglia_gradino_c` ≫ ampiezza degli scarti).
|
||
|
||
`domini.toml` è modificabile (`tipo`, `t0_s` incluso, `t1_s` escluso; ultimo dominio fino a fine dati); i domini devono essere contigui, altrimenti exit 6.
|
||
|
||
## 3. Modelli (`modelli.py`, t' = t − t0 del dominio)
|
||
|
||
| Id | Equazione | Parametri | Tipi di dominio (`[fit.modelli_per_tipo]`) |
|
||
|---|---|---|---|
|
||
| `costante` | `y = a` | a | riposo |
|
||
| `lineare` | `y = a + b·t'` | a, b | riposo |
|
||
| `esp_decad` | `y = c + A·exp(−t'/τ)` | c, A, τ | riposo, raffreddamento |
|
||
|
||
Il raffreddamento è esponenziale; il **riscaldamento** (2–3 campioni) non ha modelli: è descritto come salto (Δ = ultimo campione di salita − campione precedente, da → a, n campioni, durata). Nel raffreddamento `c` è l'asintoto (≈ ambiente) e `τ = 1/k`. Nuovo modello = voce in `MODELLI`, riga qui, nome in config.
|
||
|
||
## 4. Fit (`fit.py`)
|
||
|
||
1. Dati del dominio (raffreddamento: senza i primi `scarta_dopo_salto_n` campioni); tempo traslato.
|
||
2. Partenza: polinomi per minimi quadrati; esponenziale con griglia log-spaziata su τ (`tau_min_rel·L` … `tau_max_rel·L`, L = durata) e `c`, `A` lineari.
|
||
3. `scipy.optimize.least_squares`, perdita `perdita` (robusta `soft_l1`, scala `scala_perdita_sigma·σ`), limiti su τ.
|
||
4. IC 95 % = ±1.96·σ_p da `s²(JᵀJ)⁻¹`, moltiplicati per `√((1+ρ)/(1−ρ))` se ACF1 > `soglia_acf` (`correggi_autocorrelazione`).
|
||
5. Metriche: RSS, RMSE, R², AICc, BIC, ACF1, parametri a limite, numero di condizione. **Non identificabile** se condizione > `soglia_condizione` o un parametro (esclusi `a`, `c`) ha IC 95 % > |valore|.
|
||
|
||
### 4.1 Costanti condivise tra i raffreddamenti (`analisi.py`)
|
||
Ogni raffreddamento segue la stessa legge (stessa costante di tempo, stesso asintoto ≈ ambiente). Il raffreddamento **finale** (ultimo dominio, il più lungo) si fitta per primo con parametri liberi; i raffreddamenti **intermedi** (tra due gradini, 12–25 campioni) fissano i parametri di `raffreddamento_intermedio_fissa_da_finale` (default `c`, `tau`) ai suoi valori e hanno libera solo `A`. Motivo: con gli scarti casuali del sensore, in pochi secondi di dati τ non si identifica da solo (su dati puliti sì). Gli IC di `A` sono condizionati ai valori fissi; i parametri fissi sono marcati «(fisso)» nel report. Se manca un finale valido, o la lista è vuota, i parametri restano liberi.
|
||
|
||
### 4.2 Regola di scelta (`analisi.scegli`)
|
||
Scarta non convergenti, con parametri a limite o non identificabili. Se esistono modelli con `RMSE ≤ rmse_vs_rumore_max·σ` («adeguati») si sceglie tra questi, altrimenti tra tutti i validi; tra i modelli entro `soglia_delta_aicc` dal miglior AICc vince quello con meno parametri. Nessun modello valido ⇒ **indeterminato**; meno di `n_min_punti` campioni ⇒ non fittato. Scelto ma con RMSE > soglia·σ ⇒ «non adeguato» nel report.
|
||
|
||
## 5. CLI e file
|
||
|
||
| Comando | Funzione |
|
||
|---|---|
|
||
| `fitseg domini CSV` | passo 1: tabella, `01_domini/domini.png`, `01_domini/domini.toml` (nessun fit) |
|
||
| `fitseg analizza CSV [--domini FILE]` | tutti i passi; con `--domini` usa i domini corretti a mano al posto della proposta |
|
||
|
||
File in `output/<csv>/`: `01_domini/{domini.png, domini.toml}` · `02_sovrapposizione/{sovrapposizione_<serie>.png, dominio<k>_<serie>.png}` · `03_report/{report.md, risultati.json}`. Il report scrive in LaTeX tutte le grandezze matematiche (`$…$` inline, `$$…$$` per l'equazione scelta con i valori sostituiti; il campo `equazione` di `MODELLI` è LaTeX). Il report (indice: 1 suddivisione, 2 equazioni, 3 sovrapposizione, 4 dettaglio per dominio) incorpora le immagini con percorsi relativi.
|
||
|
||
Opzioni globali prima del sottocomando: `--config PATH`, `--output DIR` (default `[output] cartella_output`). Exit: 0 ok · 3 config non valida · 4 CSV illeggibile · 6 domini non validi.
|
||
|
||
## 6. Test
|
||
|
||
Unitari su un segnale sintetico (`tests/conftest.py`: τ = 16 s, 3 gradini, nessun disturbo a salto) e di integrazione su `input/gen_{1,2,3}.csv` (saltati se mancano). Dettaglio: README, «Test». Coperto: domini (3, 0, 1 gradino, sotto soglia, confini), recupero di τ/`c`/`A`, parametri fissi e ereditati dal raffreddamento, regola di scelta, errori di config/CSV/`domini.toml`, CLI.
|
||
|
||
## 7. Limiti noti
|
||
|
||
- **Residui autocorrelati nel raffreddamento** (ACF1 ≈ 0.7, RMSE ≈ 0.36 contro σ ≈ 0.15): scarti casuali e deriva lenta non sono nel modello; parametri buoni, IC troppo stretti, dominio «non adeguato».
|
||
- **Riscaldamento non fittato**: con 2–3 campioni si riporta solo il salto Δ; il valore dipende da quanta salita cade sul campione precedente (campioni di transizione), quindi è una stima per difetto dell'ampiezza reale del gradino.
|
||
- **Raffreddamenti intermedi**: ACF1 alto e RMSE ≈ 2σ per gli scarti: «non adeguati» anche se la forma è giusta.
|
||
- `soglia_gradino_c` va adattata se i gradini reali sono più piccoli di 20 °C o gli scarti più grandi.
|
||
- Nessun vincolo di continuità tra domini. Provato su pochi seed e con la config d'esempio di `gen_data`.
|