diff --git a/README.md b/README.md index 2299572..c8c6fa0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Temperatura Forno - Plot +# Analisi Termica Forno — Cevolani -Script per visualizzare il profilo termico di una scatola che attraversa un forno. +Script Python per l'analisi del profilo termico di una scatola che attraversa un forno industriale, con acquisizione tramite sensori IR. ## Setup (Windows) @@ -10,19 +10,100 @@ venv\Scripts\activate pip install -r requirements.txt ``` -## Utilizzo +## Avvio rapido + +Tutto il progetto è accessibile tramite un menu interattivo: + +```bat +python main.py +``` + +Il menu si ripete dopo ogni operazione finché non si preme `0` per uscire. +Le voci del menu vengono costruite automaticamente in base alle cartelle presenti nel progetto: aggiungere una nuova cartella `induttoreX/` con un `appX.py` la fa apparire automaticamente. + +--- + +## Struttura del progetto + +```text +temperatura/ +├── data.csv # dati acquisiti (input) +├── main.py # menu interattivo +├── report_completo.py # generatore report PDF + LaTeX +├── requirements.txt +├── start/ +│ ├── calcola_t_amb.py # calcola T∞ media ponderata +│ └── plot_temperatura.py # visualizza i dati raw +└── induttoreX/ # una cartella per ogni induttore + ├── appX.py # script di fit (parametri hardcoded) + ├── induttoreX.png # grafico generato + └── reportX.md # report generato +``` + +--- + +## Voci del menu + +### Calcola T ambiente + +**Script:** `start/calcola_t_amb.py` + +Calcola la temperatura ambiente media ponderata sul tempo (regola dei trapezi) usando la colonna `temp_amb IR [C]` dell'intera acquisizione. Stampa i risultati a console e genera `start/report.md`. + +> Il valore ottenuto viene usato come costante `T∞` in tutti i fit. + +--- ### Plot dati raw -```bat -python plot_temperatura.py -``` +**Script:** `start/plot_temperatura.py` -Visualizza il profilo grezzo di `temp_obj IR` e `temp_amb IR` sull'intero intervallo temporale e salva il grafico in `plot_temperatura.png`. +Visualizza il profilo grezzo di entrambe le serie (`temp_obj IR` e `temp_amb IR`) nell'intervallo definito dalle variabili `T0` e `T_END` in cima al file. Salva il grafico in `start/plot_temperatura.png`. + +--- + +### Induttore X — appX.py + +**Script:** `induttoreX/appX.py` + +Esegue la regressione non lineare sul tratto di acquisizione definito dalle variabili `T0` e `T_END` in cima allo script (modificabili manualmente). Produce: + +- `induttoreX/induttoreX.png` — grafico con dati raw e curva di fit sovrapposti +- `induttoreX/reportX.md` — equazione trovata, parametri stimati con incertezze (1σ) e R² + +Per aggiungere un nuovo induttore: copiare uno script esistente, aggiornare `T0`, `T_END` (e `W0_START`/`W0_END` se serve escludere un intervallo), e salvarlo in una nuova cartella `induttoreX/`. + +--- + +### Report completo (PDF + LaTeX) + +**Script:** `report_completo.py` + +Legge automaticamente tutti i `reportX.md` presenti nelle cartelle `induttore*/` e genera: + +- `report_completo.tex` — sorgente LaTeX compilabile con MikTeX o TeX Live +- `report_completo.pdf` — PDF professionale con cover page, scheda documento, header/footer e tabella riepilogativa finale + +Il PDF viene generato direttamente da Python tramite `reportlab` (nessuna dipendenza esterna richiesta). + +--- ## Dati -Il file `data.csv` contiene il campionamento con le colonne: -- `time since start [ms]` — tempo dall'inizio del campionamento -- `temp_amb IR [C]` — temperatura ambiente -- `temp_obj IR [C]` — temperatura della scatola +`data.csv` — colonne utilizzate: + +| Colonna | Descrizione | +| --- | --- | +| `time since start [ms]` | tempo dall'inizio (convertito in secondi negli script) | +| `temp_obj IR [C]` | temperatura della scatola (target del fit) | +| `temp_amb IR [C]` | temperatura ambiente (usata per calcolare T∞) | + +## Modello di fitting + +Tutti i fit usano il modello di raffreddamento di Newton: + +```text +T(t) = T∞ + A · exp( -(t - t₀) / τ ) +``` + +con `T∞` fissa (calcolata da `calcola_t_amb.py`) e parametri `A`, `τ` liberi, stimati con regressione non lineare (metodo TRF di `scipy.optimize.curve_fit`). diff --git a/main.py b/main.py index 171656b..44e0f21 100644 --- a/main.py +++ b/main.py @@ -4,30 +4,35 @@ from pathlib import Path BASE = Path(__file__).parent -MENU = [ - ("Calcola T ambiente (calcola_t_amb)", BASE / "start" / "calcola_t_amb.py"), - ("Plot dati raw (plot_temperatura)", BASE / "start" / "plot_temperatura.py"), - ("Induttore 1 [t = 110.81–111.56 s]", BASE / "induttore1" / "app1.py"), - ("Induttore 2 [t = 112.02–113.95 s]", BASE / "induttore2" / "app2.py"), - ("Induttore 3 [t = 115.0–133.7 s]", BASE / "induttore3" / "app3.py"), - ("Report completo LaTeX", BASE / "report_completo.py"), -] + +def build_menu() -> list[tuple[str, Path]]: + menu = [ + ("Calcola T ambiente", BASE / "start" / "calcola_t_amb.py"), + ("Plot dati raw", BASE / "start" / "plot_temperatura.py"), + ] + for folder in sorted(BASE.glob("induttore*/")): + for script in sorted(folder.glob("app*.py")): + menu.append((f"{folder.name} — {script.name}", script)) + menu.append(("Report completo (PDF + LaTeX)", BASE / "report_completo.py")) + return menu + def main(): while True: + menu = build_menu() print("\n=== Analisi Termica Forno ===\n") - for i, (label, _) in enumerate(MENU, 1): + for i, (label, _) in enumerate(menu, 1): print(f" {i}. {label}") print(" 0. Esci\n") scelta = input("Scegli: ").strip() if scelta == "0": break - if not scelta.isdigit() or not (1 <= int(scelta) <= len(MENU)): + if not scelta.isdigit() or not (1 <= int(scelta) <= len(menu)): print("Scelta non valida.") continue - _, script = MENU[int(scelta) - 1] + _, script = menu[int(scelta) - 1] subprocess.run([sys.executable, str(script)]) if __name__ == "__main__":