# Figures for the AI analysis articles

This directory contains three original figures with distinct sources:

- `replicates.png` / `.svg`: **constructed teaching data**. Six specified donor
  means, each measured in control and treated conditions with three technical
  wells. Values are deliberately chosen, not sampled from donors. The CSV has
  36 rows. Mean paired change is 6.333333333333333 arbitrary units. No test,
  interval, biological result, or time-saving estimate is reported.
- `agent-loop.png` / `.svg`: **conceptual diagram** of an analysis agent. It
  illustrates input inspection, action selection, execution, observation,
  clarification, and reporting. It is not an execution trace or performance
  measurement. The article's product description was checked against
  Gradiance's assay orchestrator, its read/fit/report/question tools, and
  assay instructions on September 8, 2026. Flow uses a separate workflow.
- `residuals.png` / `.svg`: **published Puromycin observations, independently
  refitted**. The R datasets documentation is the source for measurement units
  and experimental context. The CSV mirror is linked below. No new live app
  run was performed for this article. The historical live comparison is
  documented separately in `/blog/puromycin-kinetics`.

## Reproduce

Download `reproduce.py` and the original source CSV:

https://vincentarelbundock.github.io/Rdatasets/csv/datasets/Puromycin.csv

Source documentation:
https://stat.ethz.ch/R-manual/R-devel/library/datasets/html/Puromycin.html

The script requires NumPy, SciPy, and Matplotlib. Recorded versions are
NumPy 1.26.4, SciPy 1.17.1, and Matplotlib 3.10.9. Run:

```sh
python reproduce.py --puromycin Puromycin.csv --output generated
```

The script makes no network requests and imports no Gradiance application code.
It generates the example CSV, recomputes the two kinetic fits, writes all plots
as PNG and SVG, exports the residuals, and records numerical results and versions.

The source CSV must match SHA-256:

`389be46927d2217b13d48b5b9ec56374007a87ea607c8e6f004c17683c427c70`

Each condition is fit separately with unweighted nonlinear least squares to
`rate = Vmax * concentration / (Km + concentration)`. The initial values are
`[200, 0.05]`, with nonnegative bounds and `maxfev=10000`. Every observation is
retained. Residuals are observed minus fitted rate, and RMSE is
`sqrt(mean(residual ** 2))`. No biological comparison or interval coverage check
is performed. Both residual panels use the same limits, chosen to include all
observations. SVG text remains editable and may use a fallback font on systems
without DejaVu Sans.
