main.py dinamico + README generico senza valori hardcoded
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
abb01ecb07
commit
bccec166e4
2 files changed
+108
-22
No files matched your search
@@ -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`).
|
||||
@@ -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__":
|
||||
|
||||
Reference in new issue
Block a user