davideandClaude Sonnet 5.5 8a4309364b Report con tutte le grandezze matematiche in LaTeX
- 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>
2026-10-29 10:30:46 +01:00

fitseg

Legge un CSV t_ms,T_C,dT_C (temperatura di un sensore IR che si scalda e si raffredda), riconosce riposo, riscaldamento (la salita rapida di ogni gradino, 2–3 campioni) e raffreddamento (il decadimento esponenziale tra un gradino e l'altro e dopo l'ultimo), lo divide in domini e trova per ogni dominio e ogni serie l'equazione che lo approssima meglio, con minimi quadrati non lineari.

Risultato per dominio: modello scelto, parametri con intervallo di confidenza al 95 %, metriche (RMSE, R², AICc, BIC, autocorrelazione dei residui), un grafico dati/equazioni e un report Markdown.

Installazione

Python ≥ 3.11 e uv (curl -LsSf https://astral.sh/uv/install.sh | sh):

uv venv .venv
uv pip install -e ".[dev]"      # numpy, scipy, matplotlib; pytest e ruff per lo sviluppo

Dati di ingresso

CSV con intestazione, tempo crescente e le serie indicate in config.toml ([dati]: colonne, unità ms/s, separatore). I CSV di prova vengono dal generatore ../gen_data; metti i CSV da analizzare nella cartella input/ (la cartella è nel repository, i file *.csv no); i test di integrazione usano i seed 1–3:

mkdir -p input
for s in 1 2 3; do
  (cd ../gen_data && .venv/bin/python genera.py config.toml --seed $s -o ../EquationMiner/input/gen_$s.csv)
done

Uso

.venv/bin/fitseg domini input/gen_1.csv      # passo 1: come verrebbero suddivisi i dati (tabella, domini.png, domini.toml), nessun fit
.venv/bin/fitseg analizza input/gen_1.csv    # tutti i passi: domini, equazioni, sovrapposizione, report

--config PATH (default config.toml) e --output DIR (default output) vanno prima del sottocomando. I file di ogni analisi vanno in output/<nome del csv>/.

Correggere i domini a mano: apri output/gen_1/01_domini/domini.toml, modifica i tempi (i domini devono restare contigui) e rilancia

.venv/bin/fitseg analizza input/gen_1.csv --domini output/gen_1/01_domini/domini.toml
[[dominio]]
tipo = "riscaldamento"   # riposo | riscaldamento | raffreddamento
t0_s = 15.8              # incluso
t1_s = 17.76             # escluso (l'ultimo dominio arriva a fine dati)

Cosa produce

Una cartella per ogni CSV analizzato, con un passo per sottocartella (output/ è ignorata da git):

output/gen_1/
├── 01_domini/            suddivisione dei dati
│   ├── domini.png          dati grezzi con i domini (colore per tipo, numerati)
│   └── domini.toml         domini usati, modificabili a mano
├── 02_sovrapposizione/   dati grezzi contro le equazioni trovate
│   ├── sovrapposizione_<serie>.png   serie intera con le equazioni a tratti e i residui
│   └── dominio<k>_<serie>.png        un dominio: dati, modello scelto, altri modelli validi, residui
└── 03_report/
    ├── report.md           report completo con tutte le immagini incorporate
    └── risultati.json      tutti i fit con tutte le metriche

report.md contiene: (1) suddivisione in domini, (2) tabella delle equazioni con parametri ± IC 95 %, (3) sovrapposizione dati–equazioni, (4) dettaglio per dominio con metriche e tabella di tutti i modelli provati. Tutte le grandezze matematiche (equazioni con i valori sostituiti, parametri ± IC, \sigma, R^2, \rho_1, \Delta, t_0, criteri di scelta) sono scritte in LaTeX ($…$, $$…$$): servono un visualizzatore Markdown con supporto matematico (GitHub, VS Code, Obsidian) e le immagini come link relativi.

Come leggere il report: salto = riscaldamento descritto ma non fittato; non adeguato = RMSE oltre 1.3 volte il rumore stimato (guarda l'ACF1 dei residui); indeterminato = nessun modello valido o dominio con meno di n_min_punti campioni. Nel raffreddamento τ è la costante di tempo e c l'asintoto (≈ ambiente per T_C, ≈ 0 per dT_C).

Come funziona

  1. Domini (domini.py): un salto positivo tra due campioni consecutivi sopra soglia_gradino_c è un gradino. I campioni della salita formano un dominio riscaldamento (pochi punti, esteso ai campioni adiacenti ancora in salita). Prima del primo gradino: riposo; dopo ogni gradino: raffreddamento, fino al gradino successivo o alla fine. Con 3 gradini i domini sono 7: riposo, (riscaldamento, raffreddamento) × 3.
  2. Modelli (modelli.py): riposo → costante, lineare, esp_decad; raffreddamento → solo esp_decad y = c + A·exp(−t'/τ), con t' = t − t0 del dominio. Il riscaldamento ha troppo pochi campioni per un fit: è descritto come salto (Δ, da → a, numero di campioni, durata).
  3. Fit (fit.py): scipy.optimize.least_squares con perdita robusta; partenza dell'esponenziale da una griglia su τ. Il raffreddamento finale (il più lungo) si fitta per primo con parametri liberi; i raffreddamenti intermedi, tra due gradini (12–25 campioni), fissano c e τ ai suoi valori (stesse costanti fisiche; in pochi secondi di dati con scarti casuali τ non si stima da solo), restando libera solo A. Gli IC di A sono condizionati ai valori fissi.
  4. Scelta (analisi.py): scarta i modelli non convergenti, con parametri a limite o non identificabili; preferisce i modelli «adeguati» (RMSE ≤ rmse_vs_rumore_max × σ rumore); tra quelli entro soglia_delta_aicc dal miglior AICc vince chi ha meno parametri.

Specifica e limiti: docs/SPEC.md.

Configurazione

Tutti i valori sono in config.toml, nessun default nel codice (chiave mancante = errore, exit 3). Le principali: [domini] soglia_gradino_c (20 °C), scarta_dopo_salto_n (campioni esclusi all'inizio di ogni raffreddamento), n_min_punti; [fit.modelli_per_tipo] (modelli per tipo di dominio); [fit] raffreddamento_intermedio_fissa_da_finale (["c", "tau"], [] = parametri liberi), soglia_delta_aicc, rmse_vs_rumore_max.

Nuovo modello: voce in MODELLI di src/fitseg/modelli.py, riga in SPEC §4 e nome in [fit.modelli_per_tipo].

Test

.venv/bin/pytest                        # tutti (≈ 4 s)
.venv/bin/pytest tests/test_fit.py      # un file
.venv/bin/pytest -k raffreddamento      # per nome
.venv/bin/ruff check src tests
File Verifica Servono i CSV?
test_domini.py 7 domini con 3 gradini (riscaldamento = pochi campioni), nessun gradino, un solo gradino, gradino sotto soglia, confini vicini ai gradini veri, domini.toml (andata e ritorno, non contiguo, tipo non valido) no
test_fit.py recupero di τ, c, A su segnale sintetico (τ = 16 s), parametri fissi, τ non identificabile su tratti corti e rumorosi, analisi completa, dominio troppo corto, riproducibilità no
test_selezione.py regola di scelta no
test_config_dati.py errori di config e CSV no
test_integrazione.py domini e τ su input/gen_{1,2,3}.csv; CLI domini e analizza --domini; codici di uscita sì (altrimenti saltati)

I test unitari generano il segnale da soli (tests/conftest.py). Prova manuale: fitseg analizza input/gen_1.csv e controlla in output/gen_1/03_report/report.md 7 domini (riposo, poi riscaldamento e raffreddamento per ognuno dei 3 gradini) e τ ≈ 16 s nel raffreddamento finale; in 01_domini/domini.png ogni raffreddamento ha un colore diverso.

Codici di uscita: 0 ok · 3 configurazione non valida · 4 CSV illeggibile/non valido · 6 domini.toml non valido.

Limiti noti

  • Nel raffreddamento i residui sono autocorrelati (ACF1 ≈ 0.7) per scarti casuali e deriva lenta del sensore: i parametri sono buoni, ma gli IC sono troppo stretti e il dominio risulta «non adeguato».
  • Ogni dominio è fittato in modo indipendente (nessun vincolo di continuità); provato su pochi seed e con la config d'esempio di gen_data.
S
Description
Trova automaticamente le equazioni di riscaldamento/raffreddamento di un sensore IR a gradini: segmentazione in domini, fit robusto, grafici e report LaTeX.
Readme
440 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 93.9%
Shell 6.1%