UltrafastEngine

Build a digital twin: fit across conditions, predict, validate

A digital twin fitted to spectra at five pulse energies recovers the hidden filter and nonlinear phase, predicts two held-out energies with credible bands, and flags a twin that only fits its training data.

The story. A lab has a spectral filter and a Kerr-like element, read by a spectrometer. The written description says the filter is centred at 1030 nm, 12 nm wide, and that the nonlinear phase is 2 rad/µJ. The lab is in fact 1033.0 nm, 8.5 nm and 3.0 rad/µJ (hidden in a data generator: ultrafast_twin.synthetic). The digital twin fits the engine model to spectra measured at five pulse energies at once, with one set of shared parameters, so each parameter is constrained by all the data. Then it predicts two energies it was not fitted to, one inside and one outside the training range, with credible bands, and a validation report says whether the twin can be trusted. A second lab, whose phase saturates at high energy, shows what a failing twin looks like.

hero

the twin as a function of energy

The animation scrubs the twin from 0.2 to 3.4 µJ with its 2σ band; dots are the measurements within 0.12 µJ.

Layout (build_twin.py): ultrafast_twin.init writes a project (twin.json, system.ufs, data/*.csv); project.fit() runs the fitting plugin's multi-condition fit: parameters filter.fwhmNm, filter.centerNm and a proportional dependence kerr.bRad = slope x energy; twin.validate() simulates every condition with 12 draws from the fit covariance. The same thing from the command line: ultrafast twin init lab, ultrafast twin fit lab, ultrafast twin validate lab (set ULTRAFAST_PYTHON to a Python that has NumPy and the ultrafast package).

python build_twin.py
python make_figures.py          # optional: hero.png, animation.gif (about 10 s)
synthetic lab: a spectral filter (hidden centre 1033.0 nm, FWHM 8.5 nm) and a nonlinear phase of 3.0 rad/uJ; the description says 1030 nm, 12 nm, 2 rad/uJ
fit: five energies [0.4, 0.8, 1.2, 1.6, 2.0] uJ, one shared filter and one slope
recovered centre 1033.008 +- 0.006 nm (truth 1033.0), FWHM 8.497 +- 0.010 nm (truth 8.5), slope 2.9998 +- 0.0020 rad/uJ (truth 3.0)
held-out E1.4uJ    chi2 per point 0.98, 95 % of points inside the 2-sigma band: ok
held-out E3.0uJ    chi2 per point 0.90, 96 % of points inside the 2-sigma band: ok
verdict of the validation report: ok
saturating lab, held-out E1.4uJ    chi2 per point 11.9: flagged
saturating lab, held-out E3.0uJ    chi2 per point 180.4: flagged
saturating lab verdict: fits-training-only
checks passed

What it shows. The fit recovers the hidden centre, width and slope within their stated uncertainty (centre 1033.008 ± 0.006 nm, width 8.497 ± 0.010 nm, slope 2.9998 ± 0.0020 rad/µJ). The held-out energies are predicted at the noise level (chi² per point 0.98 and 0.90, 95 % of the points inside the 2σ band; the band is calibrated). The saturating lab is the acceptance case: the twin still fits poorly even its training data (chi² 2 to 15 per point) and its prediction of the held-out energies is off by chi² 12 and 180 per point; the report flags it fits-training-only. A twin that did not hold out data would have called it a decent fit.

Limits. The lab is synthetic: the noise is Gaussian and the model is the right one. The validation rules (flag above 3 x the training chi² or below 80 % coverage) are stated in ultrafast_twin/validate.py, not tuned.