Aggiunge _leggi_t_inf() in app1/2/3.py che legge T∞ dal report generato da calcola_t_amb.py. Solleva errore esplicito se il file non esiste o il valore non è trovato. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
import re
|
||
import pandas as pd
|
||
import numpy as np
|
||
import matplotlib.pyplot as plt
|
||
from scipy.optimize import curve_fit
|
||
from pathlib import Path
|
||
|
||
# --- Dati ---
|
||
ROOT = Path(__file__).parent.parent
|
||
df = pd.read_csv(ROOT / "data.csv")
|
||
df["time_s"] = df["time since start [ms]"] / 1000.0
|
||
|
||
def _leggi_t_inf() -> float:
|
||
report = ROOT / "start" / "report.md"
|
||
if not report.exists():
|
||
raise FileNotFoundError("start/report.md non trovato. Esegui prima 'Calcola T ambiente'.")
|
||
m = re.search(r"media ponderata\*\*\s*\|\s*\*\*([0-9.]+)\s*°C",
|
||
report.read_text(encoding="utf-8"))
|
||
if not m:
|
||
raise ValueError("T∞ non trovata in start/report.md.")
|
||
return float(m.group(1))
|
||
|
||
T_INF = _leggi_t_inf() # temperatura ambiente [°C], letta da start/report.md
|
||
T0 = 110.81 # inizio intervallo [s]
|
||
T_END = 111.56 # fine intervallo [s]
|
||
|
||
mask = (df["time_s"] >= T0) & (df["time_s"] <= T_END)
|
||
t_fit = df.loc[mask, "time_s"].values
|
||
T_fit = df.loc[mask, "temp_obj IR [C]"].values
|
||
|
||
# --- Modello: esponenziale di Newton (raffreddamento/riscaldamento) ---
|
||
def modello(t, A, tau):
|
||
return T_INF + A * np.exp(-(t - T0) / tau)
|
||
|
||
A0 = T_fit[0] - T_INF
|
||
tau0 = 5.0
|
||
|
||
popt, pcov = curve_fit(
|
||
modello, t_fit, T_fit,
|
||
p0=[A0, tau0],
|
||
method="trf",
|
||
bounds=([-np.inf, 0.01], [np.inf, np.inf])
|
||
)
|
||
A_fit, tau_fit = popt
|
||
perr = np.sqrt(np.diag(pcov))
|
||
|
||
# --- 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} ± {perr[0]:.4f} °C")
|
||
print(f"tau = {tau_fit:.4f} ± {perr[1]:.4f} s")
|
||
print(f"R² = {r2:.6f}")
|
||
print(f"\nEquazione: T(t) = {T_INF} + {A_fit:.4f} · exp(-(t - {T0}) / {tau_fit:.4f})")
|
||
|
||
# --- Curva continua per il plot ---
|
||
t_curve = np.linspace(T0, T_END, 500)
|
||
T_curve = modello(t_curve, *popt)
|
||
|
||
# --- Plot ---
|
||
fig, ax = plt.subplots(figsize=(10, 6))
|
||
|
||
ax.scatter(t_fit, T_fit,
|
||
color="steelblue", s=60, edgecolors="white", linewidths=0.5,
|
||
zorder=3, label="Dati raw (temp_obj)")
|
||
ax.plot(t_curve, T_curve,
|
||
color="tomato", linewidth=2.5,
|
||
label=f"Fit esponenziale")
|
||
|
||
ax.set_xlabel("Tempo [s]", fontsize=13)
|
||
ax.set_ylabel("Temperatura [°C]", fontsize=13)
|
||
ax.set_title(f"Induttore 1 — Fit esponenziale [{T0}–{T_END} s]", fontsize=14, fontweight="bold")
|
||
ax.tick_params(labelsize=11)
|
||
ax.legend(fontsize=11, framealpha=0.9)
|
||
ax.grid(True, which="both", alpha=0.3)
|
||
ax.minorticks_on()
|
||
|
||
eq_text = (f"$T(t) = {T_INF} + {A_fit:.2f}\\cdot e^{{-(t-{T0})/{tau_fit:.3f}}}$\n"
|
||
f"$R^2 = {r2:.4f}$")
|
||
ax.text(0.97, 0.95, eq_text, transform=ax.transAxes,
|
||
fontsize=11, verticalalignment="top", horizontalalignment="right",
|
||
bbox=dict(boxstyle="round,pad=0.4", facecolor="white", alpha=0.8))
|
||
|
||
plt.tight_layout()
|
||
plt.savefig(Path(__file__).parent / "induttore1.png", dpi=200, bbox_inches="tight")
|
||
plt.show()
|
||
|
||
# --- Report ---
|
||
report = Path(__file__).parent / "report1.md"
|
||
with open(report, "w", encoding="utf-8") as f:
|
||
f.write("# Report Induttore 1\n\n")
|
||
f.write("## Intervallo di campionamento\n\n")
|
||
f.write(f"| Parametro | Valore |\n|---|---|\n")
|
||
f.write(f"| Inizio | {T0} s |\n")
|
||
f.write(f"| Fine | {T_END} s |\n")
|
||
f.write(f"| Numero di punti | {len(t_fit)} |\n\n")
|
||
f.write("## Equazione trovata\n\n")
|
||
f.write(f"$$T(t) = {T_INF} + {A_fit:.4f} \\cdot e^{{-(t - {T0}) / {tau_fit:.4f}}}$$\n\n")
|
||
f.write("| Parametro | Valore | Incertezza (1σ) |\n|---|---|---|\n")
|
||
f.write(f"| A | {A_fit:.4f} °C | ± {perr[0]:.4f} °C |\n")
|
||
f.write(f"| τ | {tau_fit:.4f} s | ± {perr[1]:.4f} s |\n\n")
|
||
f.write("## Qualità del fit\n\n")
|
||
f.write(f"| R² | {r2:.6f} |\n|---|---|\n")
|
||
print("report1.md generato.")
|