Files
report-temperatura/fit_raffreddamento_2tratto.py
Davide Grilli 3ac42966b1 aggiunti script di fit esponenziale e report di analisi termica
- fit_raffreddamento_intero.py: fit TRF su finestra completa [115s–fine] con pesi nulli sulla zona di transizione [115.9–117.2s]
- fit_raffreddamento_2tratto.py: fit TRF sul solo tratto di raffreddamento [117.5s–fine], pesi uniformi
- report.md: analisi strutturata con calcolo T∞, parametri stimati e grafici per entrambi gli approcci
2026-04-01 10:38:37 +02:00

68 lines
1.9 KiB
Python

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# --- Dati ---
df = pd.read_csv("data.csv")
df["time_s"] = df["time since start [ms]"] / 1000.0
T_INF = 22.99 # temperatura ambiente media ponderata [°C]
T0 = 117.5 # inizio finestra di fit [s]
mask = df["time_s"] >= T0
t_fit = df.loc[mask, "time_s"].values
T_fit = df.loc[mask, "temp_obj IR [C]"].values
# --- Modello (t0 fisso) ---
def modello(t, A, tau):
return T_INF + A * np.exp(-(t - T0) / tau)
# Stima iniziale: A dal primo punto, tau arbitrario
A0 = T_fit[0] - T_INF
tau0 = 20.0
popt, pcov = curve_fit(
modello, t_fit, T_fit,
p0=[A0, tau0],
method="trf",
bounds=([0, 0.1], [np.inf, np.inf])
)
A_fit, tau_fit = popt
# --- R² ---
T_pred = modello(t_fit, *popt)
ss_res = np.sum((T_fit - T_pred) ** 2)
ss_tot = np.sum((T_fit - T_fit.mean()) ** 2)
r2 = 1 - ss_res / ss_tot
print(f"A = {A_fit:.4f} °C")
print(f"tau = {tau_fit:.4f} s")
print(f"R² = {r2:.6f}")
# --- Curva continua per il plot ---
t_curve = np.linspace(T0, df["time_s"].max(), 500)
T_curve = modello(t_curve, *popt)
# --- Plot ---
fig, ax = plt.subplots(figsize=(12, 5))
df_plot = df[df["time_s"] >= 115]
ax.plot(df_plot["time_s"], df_plot["temp_obj IR [C]"],
color="steelblue", linewidth=0.8, label="Dati raw (temp_obj)")
ax.plot(t_curve, T_curve,
color="tomato", linewidth=2, linestyle="--",
label=f"Fit: $T_{{\\infty}}$ + {A_fit:.2f}·exp(-(t-{T0})/{tau_fit:.1f})")
ax.axvline(T0, color="gray", linewidth=0.8, linestyle=":")
ax.text(T0 + 0.5, ax.get_ylim()[0], f"t₀ = {T0} s", color="gray", fontsize=8, va="bottom")
ax.set_xlabel("Tempo [s]")
ax.set_ylabel("Temperatura [°C]")
ax.set_title(f"Fit raffreddamento esponenziale | R² = {r2:.4f}")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig("fit_raffreddamento_2tratto.png", dpi=150, bbox_inches="tight")
plt.show()