Files
EquationMiner/docs/SPEC.md
T
davideandClaude Sonnet 5.5 da0964be4d Output organizzato per analisi: cartella input/, output/<csv>/ con domini, sovrapposizione e report
- 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>
2026-10-29 10:18:12 +01:00

6.3 KiB
Raw Blame History

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).

  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. 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 primi scarta_dopo_salto_n campioni sono esclusi dal fit (transizione del sensore).
  3. Prima del primo gradino riposo; tra due gradini riscaldamento; dopo l'ultimo raffreddamento. Senza gradini: un solo riposo.

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)

  1. Dati del dominio senza i primi scarta_dopo_salto_n campioni (se non riposo); 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 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_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.