- dati/ rinominata input/ (CSV ignorati, cartella tracciata con .gitkeep)
- lavoro/ sostituita da output/<nome csv>/{01_domini,02_sovrapposizione,03_report}
- report.md con indice, tabella equazioni e immagini incorporate
- sovrapposizione complessiva dati-equazioni per serie
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6.3 KiB
fitseg — specifica
Obiettivo: leggere un CSV (t_ms,T_C,dT_C, p.es. da gen_data), riconoscere riposo, riscaldamento (flusso in entrata: gradini di temperatura) e raffreddamento, dividere il tempo in domini e trovare per ogni (dominio, serie) l'equazione che lo approssima meglio. Valori configurabili: solo in config.toml. Uso: README.
1. Flusso
CSV ─► [1 DOMINI] gradini ⇒ riposo | riscaldamento… | raffreddamento ─► 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) 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 (riscaldamento, 2–4 s uno dall'altro) ognuno seguito da un decadimento esponenziale; dopo l'ultimo resta solo il raffreddamento esponenziale verso l'ambiente. Compaiono anche scarti casuali (±4 °C, rientro < 1 s).
d = diff(y)sullaserie_riferimento; gradino =d > soglia_gradino_c; rilevazioni più vicine didistanza_min_salti_campionisono lo stesso gradino.- Il gradino parte dal primo campione già in salita (si arretra finché
d > soglia_bordo_sigma · σ_d, σ_d = MAD dei salti). Quel campione apre il nuovo dominio; i primiscarta_dopo_salto_ncampioni sono esclusi dal fit (transizione del sensore). - Prima del primo gradino
riposo; tra due gradiniriscaldamento; dopo l'ultimoraffreddamento. Senza gradini: un soloriposo.
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, riscaldamento, raffreddamento |
Riscaldamento e raffreddamento sono esponenziali. Nel raffreddamento c è l'asintoto (≈ ambiente) e τ = 1/k. Nuovo modello = voce in MODELLI, riga qui, nome in config.
4. Fit (fit.py)
- Dati del dominio senza i primi
scarta_dopo_salto_ncampioni (se nonriposo); tempo traslato. - Partenza: polinomi per minimi quadrati; esponenziale con griglia log-spaziata su τ (
tau_min_rel·L…tau_max_rel·L, L = durata) ec,Alineari. scipy.optimize.least_squares, perditaperdita(robustasoft_l1, scalascala_perdita_sigma·σ), limiti su τ.- IC 95 % = ±1.96·σ_p da
s²(JᵀJ)⁻¹, moltiplicati per√((1+ρ)/(1−ρ))se ACF1 >soglia_acf(correggi_autocorrelazione). - Metriche: RSS, RMSE, R², AICc, BIC, ACF1, parametri a limite, numero di condizione. Non identificabile se condizione >
soglia_condizioneo un parametro (esclusia,c) ha IC 95 % > |valore|.
4.1 Costanti condivise tra riscaldamento e raffreddamento (analisi.py)
Dopo ogni gradino la temperatura decade con la stessa legge del raffreddamento finale. I domini di raffreddamento si fittano per primi; nei domini di riscaldamento i parametri di riscaldamento_fissa_da_raffreddamento (default c, tau) sono fissati ai loro valori e resta libera solo A. Motivo: con gli scarti casuali del sensore, in 2–4 s 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 raffreddamento 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 (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: secondo tratto con ACF1 ≈ 0.7 e RMSE ≈ 2σ per gli scarti: «non adeguato» anche se la forma è giusta.
soglia_gradino_cva 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.