README: aggiunge algoritmo.md e clear.sh alla struttura e alle voci menu. CLAUDE.md: riscrittura completa — rimuove script obsoleti e valori hardcoded, documenta architettura attuale (induttoreX/, report dinamico, T∞ da start/report.md, corporate identity in report_completo.py). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
99 lines
3.8 KiB
Markdown
99 lines
3.8 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project purpose
|
|
|
|
Thermal analysis of boxes passing through a production oven (Cevolani Italia s.r.l.), measured with IR sensors. The pipeline accepts any `data.csv` that respects the column specifications in `README.md` and produces:
|
|
|
|
- A Newton's cooling fit for each inductor zone (`induttoreX/appX.py`)
|
|
- A professional PDF report (`report_completo.pdf`) aggregating all results
|
|
|
|
The user directs the analysis (defines time windows, chooses exclusion zones); Claude implements the requested models and pipeline changes in Python.
|
|
|
|
## Setup
|
|
|
|
```bat
|
|
python -m venv venv
|
|
venv\Scripts\activate
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
## Project architecture
|
|
|
|
```text
|
|
main.py ← interactive menu, auto-discovers induttore*/ folders
|
|
start/
|
|
calcola_t_amb.py ← computes T∞ (weighted mean), writes start/report.md
|
|
plot_temperatura.py ← plots raw temp_obj and temp_amb over [T0, T_END]
|
|
induttoreX/
|
|
appX.py ← nonlinear fit for one inductor zone; params hardcoded by user
|
|
report_completo.py ← reads all induttore*/report*.md, generates .tex + .pdf
|
|
algoritmo.md ← detailed explanation of the TRF algorithm
|
|
clear.sh ← deletes all generated files (*.md, *.png, report_completo.*)
|
|
```
|
|
|
|
## Data
|
|
|
|
`data.csv` required columns (exact names):
|
|
- `time since start [ms]` — converted to seconds (`/1000`) in every script
|
|
- `temp_obj IR [C]` — object/box temperature, the fitting target
|
|
- `temp_amb IR [C]` — ambient temperature, used to compute T∞
|
|
|
|
T∞ is computed once by `calcola_t_amb.py` (weighted mean over the full acquisition) and stored in `start/report.md`. All other scripts read T∞ from there — it is **not hardcoded**.
|
|
|
|
## Fitting architecture
|
|
|
|
All fits use `scipy.optimize.curve_fit(..., method="trf")` (Trust Region Reflective, nonlinear least squares). Newton's cooling model:
|
|
|
|
```text
|
|
T(t) = T∞ + A · exp(-(t - t0) / τ)
|
|
```
|
|
|
|
Standard pattern in every `appX.py`:
|
|
|
|
```python
|
|
T0, T_END = ... # time window [s], set by user
|
|
W0_START, W0_END = ... # optional exclusion zone [s], set by user
|
|
|
|
df = pd.read_csv(ROOT / "data.csv")
|
|
df["time_s"] = df["time since start [ms]"] / 1000.0
|
|
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
|
|
|
|
sigma = np.where((t_fit >= W0_START) & (t_fit <= W0_END), 1e10, 1.0)
|
|
mask_clean = sigma < 1e10
|
|
|
|
popt, pcov = curve_fit(model, t_fit, T_fit, p0=[...], bounds=([...], [...]),
|
|
sigma=sigma, absolute_sigma=True, method="trf")
|
|
residuals = T_fit[mask_clean] - model(t_fit[mask_clean], *popt)
|
|
ss_res = np.sum(residuals**2)
|
|
ss_tot = np.sum((T_fit[mask_clean] - np.mean(T_fit[mask_clean]))**2)
|
|
R2 = 1 - ss_res / ss_tot
|
|
perr = np.sqrt(np.diag(pcov))
|
|
```
|
|
|
|
If no exclusion zone is needed, `sigma = np.ones(len(t_fit))` and `mask_clean = slice(None)`.
|
|
|
|
## Adding a new inductor
|
|
|
|
1. Copy an existing `induttoreX/appX.py` into a new folder `induttoreY/appY.py`.
|
|
2. Set `T0`, `T_END` to the desired time window.
|
|
3. Set `W0_START`, `W0_END` if a sub-interval must be excluded (or remove the exclusion logic).
|
|
4. Run via `main.py` — the menu discovers it automatically.
|
|
5. The script produces `induttoreY/induttoreY.png` and `induttoreY/reportY.md`.
|
|
6. Running `report_completo.py` includes it automatically in the PDF.
|
|
|
|
## Report generation
|
|
|
|
`report_completo.py` is fully dynamic:
|
|
- Discovers all `induttore*/report*.md` via glob
|
|
- Reads T∞ from `start/report.md`
|
|
- Renders equations and math symbols as PNG via matplotlib mathtext (no system LaTeX required)
|
|
- Outputs `report_completo.tex` and `report_completo.pdf`
|
|
|
|
Corporate identity constants (editable at the top of `report_completo.py`):
|
|
|
|
`SOCIETA`, `DIPARTIMENTO`, `DOC_NUM`, `REVISIONE`, `STATO`, `CLASSIFICAZIONE`.
|